hibernate笔记09 hibernate关联关系1

来源:互联网 发布:无间道1的知乎 编辑:程序博客网 时间:2024/06/06 00:55

--- Hibernate的一对多操作


一、 一对多映射配置

以客户和联系人为例:客户1,联系人n


第一步:创建两个实体类,客户和联系人


第二步:让两个实体类之间互相表示

(1)在客户实体类里表示多个联系人

(一个客户里面有多个联系人)





(2)在联系人实体类里面表示所属客户

(一个联系人只能属于一个客户)




第三步:配置映射关系


(1)一般一个实体类对应一个映射文件
(2)把映射最基本配置完成
(3)在映射文件中配置一对多的关系


--在客户映射文件中,表示所有联系人





--在联系人映射文件中,表示所属客户





第四步:创建核心配置文件,把映射文件放入核心配置文件中




测试:





二、一对多级联操作

级联操作

1.级联保存

(1)添加了一个客户,为这个客户添加多个联系人


2.级联删除

(1)删除某一个客户,这个客户里面的所有联系人也删除

 

3.一对多级联保存

1)添加客户,为这个客户添加一个联系人

   复杂写法:

public void testAddDemo1() {
Transaction tx = null;
SessionFactory sessionFactory = null;
Session session = null;
try {
// 1调用工具类得到sessionFactory
sessionFactory = HibernateUtils.getSessionFactory();


// 与本地线程绑定的session
// session = HibernateUtils.getSessionObject();
session = sessionFactory.openSession();


// 3: 开启事务
tx = session.beginTransaction();
// 4 操作:添加客户,为这个客户添加一个联系人
// 1)创建客户与联系人的对象
Customer customer = new Customer();
customer.setCustName("小花");
customer.setCustLevel("vip");
customer.setCustSource("网络");
customer.setCustMobile("999");
customer.setCustPhone("115");


LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("tom");
linkMan.setLkm_gender("男");
linkMan.setLkm_phone("994");


//2)在客户来表示联系人,在联系人来表示客户
//建立客户对象和联系人对象
//2.1)把联系人放到客户对象set集合里
customer.getSetLinkMan().add(linkMan);
//2.2)把客户对象放到联系人里
linkMan.setCustomer(customer);

//3)保存到数据库
session.save(customer);
session.save(linkMan);

// 5.提交事务
tx.commit();
} catch (Exception e) {
// 回滚事务
tx.rollback();
} finally {
// 6.关闭
session.close();
sessionFactory.close();
}
}

   简化写法:

-一般根据客户加联系人

第一步:在客户的映射文件进行配置

在客户映射文件里set标签设置属性 cascade="save-update"




第二步:创建客户和联系人的对象,只需要把联系人放入客户就可以了

public void testAddDemo2() {
Transaction tx = null;
SessionFactory sessionFactory = null;
Session session = null;
try {
// 1调用工具类得到sessionFactory
sessionFactory = HibernateUtils.getSessionFactory();


// 与本地线程绑定的session
// session = HibernateUtils.getSessionObject();
session = sessionFactory.openSession();


// 3: 开启事务
tx = session.beginTransaction();
// 4 操作:添加客户,为这个客户添加一个联系人
// 1)创建客户与联系人的对象
Customer customer = new Customer();
customer.setCustName("百度");
customer.setCustLevel("vip");
customer.setCustSource("网络");
customer.setCustMobile("999");
customer.setCustPhone("115");


LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("小红");
linkMan.setLkm_gender("女");
linkMan.setLkm_phone("994");


//2)在客户来表示联系人,在联系人来表示客户
//建立客户对象和联系人对象
//2.1)把联系人放到客户对象set集合里
customer.getSetLinkMan().add(linkMan);

//3)保存到数据库
session.save(customer);


// 5.提交事务
tx.commit();
} catch (Exception e) {
// 回滚事务
tx.rollback();
} finally {
// 6.关闭
session.close();
sessionFactory.close();
}
}



4.一对多级联删除


删除某个客户,把客户里面所有联系人删除


 具体实现


第一步:在客户映射文件set标签进行配置





第二步:在代码中直接删除客户 


(1)根据id查询对象,调用session里的delete方法删除




执行过程:


(1)根据id查询客户







(2)根据外键id查询联系人






(3)把联系人外键设成null






(4)删除联系人和客户







5.一对多修改操作

1.把某个联系人修改为另一个客户的联系人

//一对多级联修改
@Test
public void testUpdateDemo1() {
Transaction tx = null;
SessionFactory sessionFactory = null;
Session session = null;
try {
// 1调用工具类得到sessionFactory
sessionFactory = HibernateUtils.getSessionFactory();


// 与本地线程绑定的session
// session = HibernateUtils.getSessionObject();
session = sessionFactory.openSession();


// 3: 开启事务
tx = session.beginTransaction();
// 4 操作:修改联系人为另一个客户
// 1)根据id查询对象
Customer baidu = session.get(Customer.class, 3);
LinkMan tom = session.get(LinkMan.class, 2);


//2)设置持久化对象值(自动更新数据库)
//把联系人放到客户里面
baidu.getSetLinkMan().add(tom);
//把客户放到联系人里面
tom.setCustomer(baidu);



// 5.提交事务
tx.commit();
} catch (Exception e) {
// 回滚事务
tx.rollback();
} finally {
// 6.关闭
session.close();
sessionFactory.close();
}
}





2.inverse属性

   因为Hibernate是双向维护外键,在客户和联系人里面都需要维护外键,修改客户时修改一次外键,修改联系人是也修改一次外键,造成效率(性能)问题





解决:让其中一方不维护外键

在放弃关系维护映射文件中进行配置,在set标签上使用inverse属性