--- 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();
}
}
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();
}
}
@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属性