主要講解inverse和cascade的用法
cascade定義的是關(guān)系兩端對(duì)象到對(duì)象的級(jí)聯(lián)關(guān)系凳忙;
而inverse定義的是關(guān)系和對(duì)象的級(jí)聯(lián)關(guān)系(管理外鍵的值)饥努。
inverse
屬性默認(rèn)是false的,就是說(shuō)關(guān)系的兩端都來(lái)維護(hù)關(guān)系颜屠。
在雙向多對(duì)一里面配置到一方的集合屬性上面,inverse=true,表示關(guān)系的維護(hù)(外鍵的值)由對(duì)方(多方)來(lái)管理
cascade
all : 所有情況下均進(jìn)行關(guān)聯(lián)操作蚊荣。
none:所有情況下均不進(jìn)行關(guān)聯(lián)操作。這是默認(rèn)值莫杈。
save-update:在執(zhí)行save/update/saveOrUpdate時(shí)進(jìn)行關(guān)聯(lián)操作互例。
delete:在執(zhí)行delete時(shí)進(jìn)行關(guān)聯(lián)操作。
delete-orphan:刪除解除關(guān)系的orphan兒子
映射文件Dept.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.jege.hibernate.two.way.onetomany">
<class name="Dept" table="t_dept">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<set name="users" inverse="true">
<key column="dept_id" />
<one-to-many class="User" />
</set>
</class>
</hibernate-mapping>
測(cè)試類(lèi)TwoCrudTest.java
package com.jege.hibernate.two.way.onetomany;
import java.util.Set;
import org.hibernate.Query;
import org.hibernate.Session;
import org.junit.Before;
import org.junit.Test;
import com.jege.hibernate.util.HibernateUtils;
/**
* @author JE哥
* @email 1272434821@qq.com
* @description:雙向多對(duì)一的處理
*/
public class TwoCrudTest {
// 單個(gè)保存:一次性保存1個(gè)部門(mén)筝闹,保存3個(gè)jege
// 在單向多對(duì)一保存的時(shí)候需要先保存一方媳叨,不是會(huì)出現(xiàn)多余的update語(yǔ)句腥光,影響性能
@Before
public void before() throws Exception {
Dept dept = new Dept();
dept.setName("jege部門(mén)");
// 傳入dept的本質(zhì)是處理數(shù)據(jù)庫(kù)user表的dept_id外鍵
User user1 = new User("jegea", dept);
User user2 = new User("jegeb", dept);
Session session = HibernateUtils.INSTANCE.getSession();
session.beginTransaction();
System.out.println("保存之前:" + dept);
session.save(dept);// Hibernate會(huì)自動(dòng)把保存后的主鍵放到當(dāng)前對(duì)象的id里面
System.out.println("保存之后:" + dept);
session.save(user1);
session.save(user2);
session.getTransaction().commit();
session.close();
}
// 級(jí)聯(lián)保存:一行save方法保存3條數(shù)據(jù)(必須建立2方的關(guān)系)
// 修改Dept.hbm.xml
// <set name="users" inverse="true" cascade="save-update">
// 一次性保存:一個(gè)部門(mén),在保存這個(gè)部門(mén)下面的2個(gè)jege
@Test
public void save() throws Exception {
Dept dept = new Dept();
dept.setName("jege部門(mén)");
User user1 = new User("jege1");
User user2 = new User("jege2");
// 建立多方到一方的關(guān)系
user1.setDept(dept);
user2.setDept(dept);
// 建立一方到多方的關(guān)系
dept.getUsers().add(user1);
dept.getUsers().add(user2);
Session session = HibernateUtils.INSTANCE.getSession();
session.beginTransaction();
session.save(dept);// 持久化狀態(tài)
session.getTransaction().commit();
session.close();
}
// 級(jí)聯(lián)刪除:把一方和多方同時(shí)刪除:會(huì)出現(xiàn)3條delete語(yǔ)句
// 修改Dept.hbm.xml<set name="users" inverse="true" cascade="all">
@Test
public void delete() throws Exception {
Session session = HibernateUtils.INSTANCE.getSession();
session.beginTransaction();
session.delete(session.get(Dept.class, 1L));
session.getTransaction().commit();
session.close();
}
// 只刪除一方糊秆,不希望刪除一方包含的多方(可以先把多方的外鍵設(shè)置為null)
// 方式1:修改Dept.hbm.xml<set name="users" inverse="true">
@Test
public void delete2() throws Exception {
Session session = HibernateUtils.INSTANCE.getSession();
session.beginTransaction();
Dept dept = (Dept) session.get(Dept.class, 1L);// 持久化狀態(tài)
Set<User> users = dept.getUsers();// 持久化狀態(tài)
for (User user : users) {
user.setDept(null);// 出現(xiàn)臟數(shù)據(jù)
}
session.delete(dept);
session.getTransaction().commit();// 有事務(wù)武福,自動(dòng)更新臟數(shù)據(jù),發(fā)出update語(yǔ)句
session.close();
}
// <set name="users" inverse="true">
// 方式2:寫(xiě)類(lèi)似dml的hql來(lái)刪除
@Test
public void delete3() throws Exception {
Long deptLong = 1L;
Session session = HibernateUtils.INSTANCE.getSession();
session.beginTransaction();
// 1.先把多方的外鍵set null
String hql = "update User set dept=null where dept.id=?";
Query query = session.createQuery(hql);
query.setLong(0, deptLong);
System.out.println("受影響的行數(shù):" + query.executeUpdate());
// 2.刪除一方
hql = "delete from Dept where id=?";
query = session.createQuery(hql);
query.setLong(0, deptLong);
System.out.println("受影響的行數(shù):" + query.executeUpdate());
session.getTransaction().commit();
session.close();
}
// 方式1:在多方刪除:先獲取多方痘番,然后刪除多方
@Test
public void delete4() throws Exception {
Session session = HibernateUtils.INSTANCE.getSession();
session.beginTransaction();
User user = (User) session.get(User.class, 1L);// 持久化狀態(tài)
session.delete(user);
session.getTransaction().commit();
session.close();
}
// 方式2:在一方刪除多方:獲取一方捉片,通過(guò)一方來(lái)刪除一條多方
// 修改Dept.hbm.xml,實(shí)現(xiàn)級(jí)聯(lián)刪除解除關(guān)系的orphan兒子
// <set name="users" inverse="true" cascade="delete-orphan">
@Test
public void delete5() throws Exception {
Session session = HibernateUtils.INSTANCE.getSession();
session.beginTransaction();
Dept dept = (Dept) session.get(Dept.class, 1L);// 持久化狀態(tài)
User user = (User) session.get(User.class, 2L);// 持久化狀態(tài)
// 持久化狀態(tài)dept.getUsers()
dept.getUsers().remove(user);
session.getTransaction().commit();// 有事務(wù),自動(dòng)臟數(shù)據(jù)更新
session.close();
}
}
源碼地址
https://github.com/je-ge/hibernate
如果覺(jué)得我的文章或者代碼對(duì)您有幫助,可以請(qǐng)我喝杯咖啡汞舱。
**您的支持將鼓勵(lì)我繼續(xù)創(chuàng)作!謝謝伍纫! **