版权声明:版权所有@万星明 https://blog.csdn.net/qq_19533277/article/details/84893795
1、反转:
反转操作在映射文件中通过对集合的inverse属性设置,来控制关联关系和对象的级联关系。
inverse默认为false,关系的两端都能够控制,但会造成更新时出现重复更新的情况,产生多余的SQL语句。所以在实际开发中,一对多的时候,将一的一方inverse设置为true,即由多的一方维护关联关系;多对多则任意设置一方即可。(ps:inverse只对<set>、<one-to-many>、<many-to-many>
有效)。
2、级联:
当主控方执行保存、更新、或删除操作时,关联对象也执行相同操作。通过对cascade属性的设置来控制是否使用级联。
cascade属性值:
- save-update:在执行save、update、或saveOrUpdate时进行关联。
- delete:在执行delete操作时进行关联
- delete-orphan:表示孤儿删除,删除所有和当前对象解除关联的对象
- all:所有情况下都进行关联,但不包括delete-orphan
- all-delete-orphan:所有情况下都进行关联
- none:所有情况下都不进行关联。这个是默认的
一对多级联保存:
保存一的同时,保存一旗下的多。
/**
* 一对多级联保存
*/
@Test
public void testCascade1() {
//获得session对象
Session session = getSession();
//通过session开启事务
Transaction trans = session.beginTransaction();
//创建一个客户对象
Customer customer = new Customer();
customer.setName("马化腾");
//创建两个订单
Order order1 = new Order(1000,"硅谷");
Order order2 = new Order(2000, "大学城");
//客户关联订单
customer.getOrderSet().add(order1);
customer.getOrderSet().add(order2);
//仅保存客户
session.save(customer);
//提交事务
trans.commit();
session.close();
}
(在仅保存的那一方的xml文件中加上,cascade)
<set name="orderSet" table="orders" cascade="save-update">
<!-- 外键 -->
<key>
<column name="customer_id"/>
</key>
<one-to-many class="wan.bean.Order" />
</set>
一对多级联删除:
删除一的同时,删除一旗下的多。如果不配置xml,则只删除一,然后将一旗下的多的外键置null。
/**
* 一对多级联删除(如果不在xml中配置cascade="delete",则只能删除customer,然后将order的外键置null)
*/
@Test
public void testCascade2() {
//获得session对象
Session session = getSession();
//通过session开启事务
Transaction trans = session.beginTransaction();
//得到一个客户对象
Customer customer = session.get(Customer.class,40023);
//删除客户
session.delete(customer);
//提交事务
trans.commit();
session.close();
}
<set name="orderSet" table="orders" cascade="delete">
<!-- 外键 -->
<key>
<column name="customer_id"/>
</key>
<one-to-many class="wan.bean.Order" />
</set>
一对多孤儿删除:
删除多,且只删除外键为null的多。
/**
* 孤儿删除:删除多,且只删除外键为null的多
*/
@Test
public void testCascade3() {
//获得session对象
Session session = getSession();
//通过session开启事务
Transaction trans = session.beginTransaction();
//得到一个客户对象
Customer customer = session.get(Customer.class,40022);
//得到客户旗下的订单
Order order1 = session.get(Order.class,29);
Order order2 = session.get(Order.class,30);
//解除关系
customer.getOrderSet().remove(order1);
customer.getOrderSet().remove(order2);
//提交事务
trans.commit();
session.close();
}
<set name="orderSet" table="orders" cascade="delete-orphan">
<!-- 外键 -->
<key>
<column name="customer_id"/>
</key>
<one-to-many class="wan.bean.Order" />
</set>
多对多级联保存:
/**
* 级联添加(只在teacher.hbm.xml中添加级联属性为save-update)
*/
@Test
public void testAdd3() {
//获得session对象
Session session = getSession();
//通过session开启事务
Transaction trans = session.beginTransaction();
//创建两个老师,两个班级
Teacher t1 = new Teacher("马云");
Teacher t2 = new Teacher("马化腾");
Classes c1 = new Classes("通信141");
Classes c2 = new Classes("通信142");
//建立联系
t1.getClassesSet().add(c1);
t1.getClassesSet().add(c2);
t2.getClassesSet().add(c1);
t2.getClassesSet().add(c2);
session.save(t1);
session.save(t2);
trans.commit();
session.close();
}
<set name="classesSet" table="classes_teacher" cascade="save-update">
<key>
<column name="t_id" />
</key>
<!-- 多对多对应Classes POJO类,该类对应中间表的c_id -->
<many-to-many class="Classes" column="c_id"/>
</set>
或者:
/**
* 级联添加(只在两张hbm.xml中都添加级联属性为save-update)
*/
@Test
public void testAdd4() {
//获得session对象
Session session = getSession();
//通过session开启事务
Transaction trans = session.beginTransaction();
//创建两个老师,两个班级
Teacher t1 = new Teacher("刘强东");
Teacher t2 = new Teacher("雷军");
Classes c1 = new Classes("通信141");
Classes c2 = new Classes("通信142");
//建立联系
t1.getClassesSet().add(c1);
t1.getClassesSet().add(c2);
t2.getClassesSet().add(c1);
t2.getClassesSet().add(c2);
c1.getTeacherSet().add(t1);
c1.getTeacherSet().add(t2);
c2.getTeacherSet().add(t1);
c2.getTeacherSet().add(t2);
session.save(t1);
trans.commit();
session.close();
}
多对多级联删除:
/**
* 删除(无级联配置,删除该Teacher对象和中间表)
*/
@Test
public void testDel2() {
//获得session对象
Session session = getSession();
//通过session开启事务
Transaction trans = session.beginTransaction();
Teacher teacher = session.get(Teacher.class, 31);
session.delete(teacher);
trans.commit();
session.close();
}
/**
* 级联删除(在两个hbm.xml中加入级联删除,且在Classes.hbm.xml中加入inverse="true")
* 将会删除和该Teacher有关的一切
*/
@Test
public void testDel1() {
//获得session对象
Session session = getSession();
//通过session开启事务
Transaction trans = session.beginTransaction();
Teacher teacher = (Teacher) session.get(Teacher.class, 30);
session.delete(teacher);
trans.commit();
session.close();
}