3.Hibernate中多表操作

一、表與表之間關係分析

一對多建表原則:在多的一方創建外鍵指向一的一方的主鍵;
多對多建表原則:創建一箇中間表,中間表至少有兩個字段分別作爲外鍵指向多對多雙方的主鍵;
一對一建表原則:(瞭解)有兩種對應方式,即唯一外鍵對應、主鍵對應。唯一外鍵對應方式中,可將其中一張表看成一對多中的n = 1,然後再該表中添加唯一外鍵;主鍵對應方式中,直接將兩張表的主鍵進行一一對應即可。

具體可參考:SQL多表操作

二、Hibernate中一對多關係

1.建立工程,引入jar包
具體參考:Hibernate項目創建
2.創建表
創建客戶表

CREATE TABLE `cst_customer` (
  `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客戶編號(主鍵)',
  `cust_name` varchar(32) NOT NULL COMMENT '客戶名稱(公司名稱)',
  `cust_source` varchar(32) DEFAULT NULL COMMENT '客戶信息來源',
  `cust_industry` varchar(32) DEFAULT NULL COMMENT '客戶所屬行業',
  `cust_level` varchar(32) DEFAULT NULL COMMENT '客戶級別',
  `cust_phone` varchar(64) DEFAULT NULL COMMENT '固定電話',
  `cust_mobile` varchar(16) DEFAULT NULL COMMENT '移動電話',
  PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

創建聯繫人表

CREATE TABLE `cst_linkman` (
  `lkm_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '聯繫人編號(主鍵)',
  `lkm_name` varchar(16) DEFAULT NULL COMMENT '聯繫人姓名',
  `lkm_cust_id` bigint(32) NOT NULL COMMENT '客戶id',
  `lkm_gender` char(1) DEFAULT NULL COMMENT '聯繫人性別',
  `lkm_phone` varchar(16) DEFAULT NULL COMMENT '聯繫人辦公電話',
  `lkm_mobile` varchar(16) DEFAULT NULL COMMENT '聯繫人手機',
  `lkm_email` varchar(64) DEFAULT NULL COMMENT '聯繫人郵箱',
  `lkm_qq` varchar(16) DEFAULT NULL COMMENT '聯繫人qq',
  `lkm_position` varchar(16) DEFAULT NULL COMMENT '聯繫人職位',
  `lkm_memo` varchar(512) DEFAULT NULL COMMENT '聯繫人備註',
  PRIMARY KEY (`lkm_id`),
  KEY `FK_cst_linkman_lkm_cust_id` (`lkm_cust_id`),
  CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

兩個表之間的關係:一對多的關係, 聯繫人表中的外鍵lkm_cust_id指向客戶表中的主鍵cust_id
在這裏插入圖片描述
3.創建實體類(客戶與聯繫人)
通過ORM(對象關係映射)的方式,將對象與數據庫中的表建立聯繫,從而也可以建立客戶類與聯繫人類之間的關係。這裏以一對多的方式舉例:
客戶實體類:Customer(這裏簡寫,省略get和set方法)

public class Customer {   //一的一方
    private Long cust_id;
    private String cust_name;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_phone;
    private String cust_mobile;
    
    /*這裏放置多的一方的集合,從而使得客戶與聯繫人雙向關聯,Hibernate中使用的集合爲Set*/
	private Set<Linkman> linkmans = new HashSet<Linkman>();
}

聯繫人實體類:Linkman(這裏簡寫,省略get和set方法)
注意:這裏聯繫人表爲多的一方,存在外鍵,但是這裏的實體類中使用Customer類(一的一方)的對象來代替外鍵。

public class Linkman {   //多的一方
    private Long lkm_id;
    private String name;
    private String lkm_gender;
    private String lkm_phone;
    private String lkm_mobile;
    private String lkm_email;
    private String lkm_qq;
    private String lkm_position;
    private String lkm_memo;
    
    /*注意:這裏的外鍵使用Customer類(一的一方)的對象來代替*/
    private Customer customer;
}

4.創建工具類

public class HibernateUtils {

	public static final Configuration cfg;
	public static final SessionFactory sf;
	
	static{
		cfg = new Configuration().configure();
		sf = cfg.buildSessionFactory();
	}
	
	public static Session openSession(){
		return sf.openSession();
	}
	
	public static Session getCurrentSession() {
		return sf.getCurrentSession();
	}
}

5.創建配置文件
映射配置文件
Customer.hbn.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
    <class name = "start_2.Customer" table = "cst_customer">
        <!-- 建立OID與主鍵映射 -->
        <id name = "cust_id" column = "cust_id">
            <generator class="native"/>
        </id>
        <!-- 建立普通屬性與數據庫表字段的映射 -->
        <property name="cust_name" column = "cust_name"/>
        <property name="cust_source" column = "cust_source"/>
        <property name="cust_industry" column = "cust_industry"/>
        <property name="cust_level" column = "cust_level"/>
        <property name="cust_phone" column = "cust_phone"/>
        <property name="cust_mobile" column = "cust_mobile"/>
        <!-- 配置一對多的映射:放置多的一方的集合,set標籤中name放置多的一方的對象集合的屬性名稱 -->
        <set name="linkmans">
            <!-- key標籤,column中放的是多的一方的外鍵名稱 -->
            <key column = "lkm_cust_id"/>
            <!-- one-to-many 標籤,class中放的是多的一方的類的全路徑(即包含包名的路徑) -->
            <one-to-many class = "start_2.Linkman"/>
        </set>
    </class>
</hibernate-mapping>

Link.hbn.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
    <class name = "start_2.Linkman" table = "cst_linkman">
        <!-- 建立OID與主鍵映射 -->
        <id name = "lkm_id" column = "lkm_id">
            <generator class="native"/>
        </id>
        <!-- 建立普通屬性與數據庫表字段的映射 -->
        <property name="lkm_name"/>
        <property name="lkm_gender"/>
        <property name="lkm_phone"/>
        <property name="lkm_mobile"/>
        <property name="lkm_email"/>
        <property name="lkm_qq"/>
        <property name="lkm_position"/>
        <property name="lkm_memo"/>
        
        <!-- 配置多對一的映射:放置的是一的一方的對象 -->
        <!-- many-to-one標籤:
            name    : 一的一方的對象的屬性名稱;
            class   :一的一方的類的全路徑;
            column  :在多的一方的表的外鍵名稱;
        -->
        <many-to-one name="customer" class = "start_2.Customer" column = "lkm_cust_id"/>
    </class>
</hibernate-mapping>

核心配置文件
hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
	
<hibernate-configuration>
    <session-factory>
        <!-- 連接數據庫的基本參數 -->
        <property name = "hibernate.connection.driver_class" >com.mysql.jdbc.Driver</property>
        <property name = "hibernate.connection.url" >jdbc:mysql:///hibernate_start2</property>
        <property name = "hibernate.connection.username" >root</property>
        <property name = "hibernate.connection.password" >2e5y8hxf</property>
        
        <!-- hibernate方言設置 -->
        <property name = "hibernate.dialect" >org.hibernate.dialect.MySQLDialect</property>

        
        <!-- 可選配置 -->
        <!-- 打印SQL -->
        <property name = "hibernate.show_sql">true</property>
        <!-- 格式化SQL -->
        <property name = "hibernate.format_sql">true</property>
        <!-- 自動創建表 -->
        <property name = "hibernate.hbm2ddl.auto">update</property>
        
        <!-- 配置當前線程綁定的 Session -->
        <property name="hibernate.current_session_context_class">thread</property>
        
        <mapping resource = "start_2/Customer.hbn.xml"/>
        <mapping resource = "start_2/Linkman.hbn.xml"/>
    </session-factory>    

</hibernate-configuration>

6.編寫測試類

public class TestDemo {
	@Test
    public void demo1() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	//創建兩個客戶
    	Customer customer1 = new Customer();
    	customer1.setCust_name("張三丰");
    	Customer customer2 = new Customer();
    	customer2.setCust_name("張無忌");
    	
    	//創建三個聯繫人
    	Linkman linkman1 = new Linkman();
    	linkman1.setLkm_name("郭襄");
    	Linkman linkman2 = new Linkman();
    	linkman2.setLkm_name("趙敏");
    	Linkman linkman3 = new Linkman();
    	linkman3.setLkm_name("周芷若");
    	
    	//設置關係
    	linkman1.setCustomer(customer1);
    	linkman2.setCustomer(customer1);
    	linkman3.setCustomer(customer2);
    	customer1.getLinkmans().add(linkman1);
    	customer1.getLinkmans().add(linkman2);
    	customer2.getLinkmans().add(linkman3);
    	
    	//保存數據
    	session.save(customer1);
    	session.save(customer2);
    	session.save(linkman1);
    	session.save(linkman2);
    	session.save(linkman3);
    	
    	tx.commit();    	
    }
}

測試結果:
在這裏插入圖片描述
在這裏插入圖片描述
7.一對多中的級聯保存或更新
問題由來:當兩張表(A和B)建立起相互關聯的關係時,若此時只保存表A中的對象customer,則customer會成爲持久態對象,這時對象linkman未保存到表B中,成爲瞬時態對象。由於持久態對象不能與瞬時態對象進行關聯。
級聯:指操作(比如保存操作)一個對象時,會同時操作其關聯的對象。
級聯的方向性
  操作一的一方的時候,看看其是否操作到多的一方;
  操作多的一方的時候,看看其是否操作到一的一方;
舉例
操作一的一方,級聯到多的一方:在Customer.hbn.xml中加上cascade = “save-update”
在這裏插入圖片描述
操作多的一方,級聯到一的一方:在Linkman.hbn.xml中加上cascade = “save-update”
在這裏插入圖片描述
測試類代碼:

	@Test
	public void demo2() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	Customer customer = new Customer();
    	customer.setCust_name("令狐沖1");
    	Linkman linkman = new Linkman();
    	linkman.setLkm_name("任盈盈1");
    	
    	linkman.setCustomer(customer);
    	customer.getLinkmans().add(linkman);
    	
    	//session.save(customer);
    	session.save(linkman);
    	tx.commit();
	}

8.對象導航測試
概述:對象的導航即對象之間的關聯關係和順序,下面舉例說明;
舉例

	@Test
	public void demo3() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	Customer customer = new Customer();
    	customer.setCust_name("張無忌");
    	
    	Linkman linkman1 = new Linkman();
    	linkman1.setLkm_name("趙敏");
    	Linkman linkman2 = new Linkman();
    	linkman2.setLkm_name("周芷若");
    	Linkman linkman3 = new Linkman();
    	linkman3.setLkm_name("小昭");
   	
    	linkman1.setCustomer(customer);
    	customer.getLinkmans().add(linkman2);
    	customer.getLinkmans().add(linkman3);

    	//session.save(linkman1);   //發送4條insert語句
    	//session.save(customer);     //發送3條insert語句
    	session.save(linkman2);     //發送1條insert語句
    	tx.commit();
	}

測試結果
session.save(linkman1); //發送4條insert語句
分析:這時,linkman1被保存,同時linkman1關聯的customer也被保存,之後與customer關聯的linkman2和linkman3也被保存,所以一共執行了4條insert語句。
在這裏插入圖片描述
session.save(customer); //發送3條insert語句
分析:這時保存customer,同時存了customer關聯的linkman2和linkman3,這裏的linkman1與customer是單向關聯,所以不能通過customer來級聯linkman1。
在這裏插入圖片描述
session.save(linkman2); //發送1條insert語句
分析:這裏linkman2與customer是從customer到linkman2的單向關聯,所以不能從linkman2級聯出customer,所以只有linkman2一條insert語句。
在這裏插入圖片描述
9.一對多中的級聯刪除
概述:在JDBC中,無法刪除一對多關聯中“一”一方的表數據,必須先刪除“多”的一方中的表數據,才能解除關聯,才能夠刪除“一”的一方的表數據。在Hibernate中,默認情況下,可以直接刪除存在關聯的“一”的一方的表數據,其實現過程是先在“多”的一方將外鍵置空,然後刪除“一”的一方的相關數據;
級聯刪除:在Hibernate中不使用默認的情況,可以直接刪除“一”的一方的數據,同時級聯刪除“多”的一方的相關聯數據(比如:刪除了一個客戶信息,同時刪除了這個客戶關聯的所有訂單信息)。另外,也可以反過來,刪除訂單信息,同時也刪除了客戶信息,但是不常用,這裏忽略!
舉例
在這裏插入圖片描述

	@Test
	public void demo4() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	Customer customer = session.get(Customer.class, 1l);
    	session.delete(customer);

    	tx.commit();
	}

測試結果
刪除前:
在這裏插入圖片描述
刪除後:
在這裏插入圖片描述
10.inverse配置
雙向關係維護產生的多餘的SQL語句:由於“一”的一方和“多”的一方都能夠維護“多”的一方表中的外鍵,所以會產生髮送兩次SQL語句去更新“多”的一方表中的外鍵;
發送兩次更新外鍵代碼

	@Test
	public void demo5() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	Customer customer = session.get(Customer.class, 2l);
    	Linkman linkman = session.get(Linkman.class, 1l);
    	
    	linkman.setCustomer(customer);
    	customer.getLinkmans().add(linkman);

    	tx.commit();
	}

這裏產生兩條update外鍵lkm_cust_id的語句:
在這裏插入圖片描述
使用inverse配置:inverse默認爲false,爲擁有外鍵維護權;
在這裏插入圖片描述
代碼:

	@Test
	public void demo5() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	Customer customer = session.get(Customer.class, 2l);
    	Linkman linkman = session.get(Linkman.class, 1l);
    	
    	linkman.setCustomer(customer);   //linkman可以維護外鍵,也就是說可以修改
    	customer.getLinkmans().add(linkman);   //這裏customer配置文件中放棄外鍵維護權,所以不能修改外鍵

    	tx.commit();
	}

這時,只發送一條update修改外鍵的語句:
在這裏插入圖片描述
cascade與inverse的區別:cascade是級聯操作,可以在操作一個表的同時操作另外一張表;inverse是放棄外鍵維護權,若設置爲true,則該配置文件相應的對象將失去外鍵維護權,即通過該對象修改不了外鍵。

三、Hibernate中多對多關係

1.建立工程,引入jar包
2.創建表
由於是多對多的關係,所以需要創建三個表:用戶表、角色表、中間表
用戶表:

CREATE TABLE `sys_user` (
  `user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用戶id',
  `user_code` varchar(32) NOT NULL COMMENT '用戶賬號',
  `user_name` varchar(64) NOT NULL COMMENT '用戶名稱',
  `user_password` varchar(32) NOT NULL COMMENT '用戶密碼',
  `user_state` char(1) NOT NULL COMMENT '1:正常,0:暫停',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

角色表:

CREATE TABLE `sys_role` (
  `role_id` bigint(32) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(32) NOT NULL COMMENT '角色名稱',
  `role_memo` varchar(128) DEFAULT NULL COMMENT '備註',
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

中間表:

CREATE TABLE `sys_user_role` (
  `role_id` bigint(32) NOT NULL COMMENT '角色id',
  `user_id` bigint(32) NOT NULL COMMENT '用戶id',
  PRIMARY KEY (`role_id`,`user_id`),
  KEY `FK_user_role_user_id` (`user_id`),
  CONSTRAINT `FK_user_role_role_id` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`role_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `FK_user_role_user_id` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3.創建實體類
要創建的實體類包含兩個:User.java 和Role.java (這裏省略get和set方法),在多對多中,要表示兩個類之間的關係,需要在類中放置對方的集合。
User.java

public class User {
    private Long user_id;
    private String user_code;
    private String user_name;
    private String user_password;
    private String user_state;
    private Set<Role> roles = new HashSet<Role>();
}

Role.java

public class Role {
    private Long role_id;
    private String role_name;
    private String role_memo;
    private Set<User> users = new HashSet<User>();
}

4.創建映射配置文件
映射配置文件包括:User類映射配置文件(User.hbn.xml)和Role類映射配置文件(Role.hbn.xml)。
User.hbn.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
    <class name = "start_3.User" table = "sys_user">
        <!-- 建立OID與主鍵映射 -->
        <id name = "user_id" column = "user_id">
            <generator class="native"/>
        </id>
        <!-- 建立普通屬性與數據庫表字段的映射 -->
        <property name="user_code" column = "user_code"/>
        <property name="user_name" column = "user_name"/>
        <property name="user_password" column = "user_password"/>
        <property name="user_state" column = "user_state"/>
        
        <!-- 配置與User的多對多的關係映射 -->
        <!-- Set標籤:
                *name     :相關的對方的集合的屬性名稱
                *table    :多對多的關係需要使用中間表,這裏放的是中間表的名稱
            
            Key標籤:
                *column    :當前的對象對應的中間表中的外鍵名稱
                
            many-to-many標籤:
                *class     :對方類的全路徑
                *column    :對方的對象在中間表的外鍵名稱      
         -->
        <set name="roles" table = "sys_user_role">
            <key column = "user_id"/>
            <many-to-many class = "start_3.Role" column = "role_id"/>
        </set>
    </class>
</hibernate-mapping>

Role.hbn.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping>
    <class name = "start_3.Role" table = "sys_role">
        <!-- 建立OID與主鍵映射 -->
        <id name = "role_id" column = "role_id">
            <generator class="native"/>
        </id>
        <!-- 建立普通屬性與數據庫表字段的映射 -->
        <property name="role_name" column = "role_name"/>
        <property name="role_memo" column = "role_memo"/>

        <!-- 配置與User的多對多的關係映射 -->
        <!-- Set標籤:
                *name     :相關的對方的集合的屬性名稱
                *table    :多對多的關係需要使用中間表,這裏放的是中間表的名稱
            
            Key標籤:
                *column    :當前的對象對應的中間表中的外鍵名稱
                
            many-to-many標籤:
                *class     :對方類的全路徑
                *column    :對方的對象在中間表的外鍵名稱      
         -->
        <set name="users" table = "sys_user_role" inverse = "true">
            <key column = "role_id"/>
            <many-to-many class = "start_3.User" column = "user_id"/>
        </set>
    </class>
</hibernate-mapping>

注意:在多對多中,對於雙向關聯,只能有一方能夠維護中間表中的外鍵,如果雙方都能維護中間表中的外鍵,則會出現中間表中的主鍵重複的情況(中間表中的主鍵可以認爲是由兩個元素共同構成,即user_id和role_id)。一般而已,通常是被動方放棄外鍵維護權利,另外,若不採用雙向關聯,則雙方都可以有外鍵維護權利。
5.創建測試類

public class TestDemo1 {
    @Test
    public void demo1() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	//創建2個用戶
    	User user1 = new User();
    	user1.setUser_name("陳赫");
    	User user2 = new User();
    	user2.setUser_name("鄧超");
    	
    	//創建3個角色
    	Role role1 = new Role();
    	role1.setRole_name("美國隊長");
    	Role role2 = new Role();
    	role2.setRole_name("鋼鐵俠");
    	Role role3 = new Role();
    	role3.setRole_name("蜻蜓隊長");
    	
    	//這裏採用雙向關聯
    	user1.getRoles().add(role1);
    	user1.getRoles().add(role2);
    	user2.getRoles().add(role2);
    	user2.getRoles().add(role3);
    	role1.getUsers().add(user1);
    	role2.getUsers().add(user1);
    	role2.getUsers().add(user2);
    	role3.getUsers().add(user2);
    	
    	//保存數據
    	session.save(user1);
    	session.save(user2);
    	session.save(role1);
    	session.save(role2);
    	session.save(role3);
    	
    	tx.commit();
    }
}

測試結果:
在這裏插入圖片描述
6.多對多關係的級聯保存
舉例
配置文件設置:在User.hbn.xml配置文件中設置
在這裏插入圖片描述
代碼:

    @Test
    public void demo2() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	//創建2個用戶
    	User user1 = new User();
    	user1.setUser_name("陳赫");
    	
    	//創建3個角色
    	Role role1 = new Role();
    	role1.setRole_name("美國隊長");

    	//這裏採用雙向關聯
    	user1.getRoles().add(role1);
    	//role1.getUsers().add(user1);    //因爲role1無外鍵維護權利,所以這行代碼冗餘
    	
    	session.save(user1);
 	
    	tx.commit();
    }

分析:這裏的role1爲被動方,設置放棄外鍵維護權利,所以只能保存user1來級聯保存role1,而不能通過保存role1來級聯保存user1。

測試結果:級聯保存成功。

7.多對多關係的級聯刪除
舉例
配置文件:在User.hbn.xml中配置
在這裏插入圖片描述
代碼:

    @Test
    public void demo3() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	//獲取要刪除的對象數據
        User user1 = session.get(User.class, 1l);
        
        session.delete(user1);
 	
    	tx.commit();
    }

刪除前:
在這裏插入圖片描述
刪除後:
在這裏插入圖片描述
注意事項:級聯刪除時,比如刪除用戶id爲1的用戶,同時刪除用戶1級聯的角色1和2,若角色1或2也與其他用戶相關聯,則刪除不了,報錯。

8.多對多關係中的其他操作
概述:在多對多關係中,這裏的其他操作包含:給用戶選擇角色、給用戶改選角色、給用戶刪除角色,這裏的操作主要是對集合的操作

給用戶選擇角色

    @Test
    public void demo4() {
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	
        User user1 = session.get(User.class, 1l);
        Role role3 = session.get(Role.class, 3l);
        user1.getRoles().add(role3);
 	
    	tx.commit();
    }

給用戶改選角色

    @Test
    public void demo5() {  //用戶1選擇的角色3,改選成角色2
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	
        User user1 = session.get(User.class, 1l);
        Role role2 = session.get(Role.class, 2l);
        Role role3 = session.get(Role.class, 3l);
        user1.getRoles().remove(role3);
        user1.getRoles().add(role2);
 	
    	tx.commit();
    }

給用戶刪除角色

    @Test
    public void demo5() {  //用戶1刪除角色2
    	Session session = HibernateUtils.getCurrentSession();
    	Transaction tx = session.beginTransaction();
    	
    	
        User user1 = session.get(User.class, 1l);
        Role role2 = session.get(Role.class, 2l);
        user1.getRoles().remove(role2);

 	
    	tx.commit();
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章