Hibernate中表与表之间的关联多对多,级联保存,级联删除

时间:2021-08-15 13:31:29

 

Hibernate中表与表之间的关联多对多,级联保存,级联删除

 

第一步:创建两个实体类:用户和角色实体类,多对多关系,并让两个实体类之间互相关联:

  用户实体类:

Hibernate中表与表之间的关联多对多,级联保存,级联删除Hibernate中表与表之间的关联多对多,级联保存,级联删除
 1 package com.yinfu.entity;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class User {
 7 
 8     private int id;
 9     private String username;
10     private String password;
11     private String address;
12     //一个用户多个角色
13     private Set<Role> setRole = new HashSet<>();
14     public Set<Role> getSetRole() {
15         return setRole;
16     }
17     public void setSetRole(Set<Role> setRole) {
18         this.setRole = setRole;
19     }
20     public int getId() {
21         return id;
22     }
23     public void setId(int id) {
24         this.id = id;
25     }
26     public String getUsername() {
27         return username;
28     }
29     public void setUsername(String username) {
30         this.username = username;
31     }
32     public String getPassword() {
33         return password;
34     }
35     public void setPassword(String password) {
36         this.password = password;
37     }
38     public String getAddress() {
39         return address;
40     }
41     public void setAddress(String address) {
42         this.address = address;
43     }
44     @Override
45     public String toString() {
46         return "User [id=" + id + ", username=" + username + ", password=" + password + ", address=" + address + "]";
47     }
48     
49 }
User

  角色实体类:

Hibernate中表与表之间的关联多对多,级联保存,级联删除Hibernate中表与表之间的关联多对多,级联保存,级联删除
 1 package com.yinfu.entity;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class Role {
 7 
 8     private Integer role_id;
 9     private String role_name;
10     private String role_memo;
11     //一个角色多个用户
12     private Set<User> setUser = new HashSet<>();
13     public Set<User> getSetUser() {
14         return setUser;
15     }
16     public void setSetUser(Set<User> setUser) {
17         this.setUser = setUser;
18     }
19     public Integer getRole_id() {
20         return role_id;
21     }
22     public void setRole_id(Integer role_id) {
23         this.role_id = role_id;
24     }
25     public String getRole_name() {
26         return role_name;
27     }
28     public void setRole_name(String role_name) {
29         this.role_name = role_name;
30     }
31     public String getRole_memo() {
32         return role_memo;
33     }
34     public void setRole_memo(String role_memo) {
35         this.role_memo = role_memo;
36     }
37 }
Role

第二步:创建实体类与表对应的配置文件:

  创建用户配置文件:

Hibernate中表与表之间的关联多对多,级联保存,级联删除Hibernate中表与表之间的关联多对多,级联保存,级联删除
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6  <class name="com.yinfu.entity.User" table="t_user">
 7        <id name="id" column="id">
 8            <generator class="native"></generator>
 9        </id>
10        <property name="username" column="username"></property>
11        <property name="password" column="password"></property>
12        <property name="address" column="address"></property>
13        <!-- 里面表示所有角色
14                name属性:用户实体类中对应的角色的属性
15                table属性:表示第三张表的名字
16         -->
17        <set name="setRole" table="user_role">
18            <!-- key配置
19                当前映射文件在第三张表中外键的名称
20            -->
21            <key column="userid"></key>
22            <!-- class:角色实体类的全类名 
23               column:角色在第三张表中的外键名称
24            -->
25            <many-to-many class="com.yinfu.entity.Role" column="roleid"></many-to-many>
26        </set>
27  </class>
28 </hibernate-mapping>
User.hbm.xml

  创建角色的配置文件:

Hibernate中表与表之间的关联多对多,级联保存,级联删除Hibernate中表与表之间的关联多对多,级联保存,级联删除
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6  <class name="com.yinfu.entity.Role" table="t_role">
 7        <id name="role_id" column="role_id">
 8            <generator class="native"></generator>
 9        </id>
10        <property name="role_name" column="role_name"></property>
11        <property name="role_memo" column="role_memo"></property>
12        <set name="setUser" table="user_role">
13            <key column="roleid"></key>
14            <many-to-many class="com.yinfu.entity.User" column="userid"></many-to-many>
15        </set>
16  </class>
17 </hibernate-mapping>
Role.hbm.xml

第四步:创建Hibernate的核心配置文件hibernate.cfg.xml:

Hibernate中表与表之间的关联多对多,级联保存,级联删除Hibernate中表与表之间的关联多对多,级联保存,级联删除
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6 <!-- 此配置文件的文件名和位置是固定的的
 7     文件名:hibernate.cfg.xml
 8     位置:要写在src文件中
 9  -->
10     <session-factory>
11         <!-- 第一部分:配置数据库信息 -->
12         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
13         <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
14         <property name="hibernate.connection.username">root</property>
15         <property name="hibernate.connection.password">song12345</property>
16         
17         <!-- 第二部分:配置hibernate信息(可有可无) -->
18         <!-- 输出底层的SQL语句 -->
19         <property name="hibernate.show_sql">true</property>
20         <!-- 对底曾语句进行格式化 -->
21         <property name="hibernate.format_sql">true</property>
22         <!-- hibernate帮创建表,需要配置
23             update:如果有表就更新,没有表就创建
24          -->
25         <property name="hibernate.hbm2ddl.auto">update</property>
26         <!-- 配置数据库的方言 
27             识别不同数据库中的特有的语句和关键字
28             比如:分页查询
29                     MySQL关键字是limit
30                     oracle中的使用的是top-n分析中的rownum
31         -->
32         <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
33         <!-- 指定线程管理方式,与本地线程进行绑定,实现单线程操作 -->
34         <property name="hibernate.current_session_context_class">thread</property>
35     
36         <!-- 第三部分:把映射文件放到核心配置文件中 -->
37         <mapping resource="com/yinfu/entity/Role.hbm.xml"/>
38         <mapping resource="com/yinfu/entity/User.hbm.xml"/>
39     </session-factory>
40     
41 </hibernate-configuration>
hibernate.cfg.xml

  创建工具类生成SessionFactory和session对象

Hibernate中表与表之间的关联多对多,级联保存,级联删除Hibernate中表与表之间的关联多对多,级联保存,级联删除
 1 package com.yinfu.utils;
 2 
 3 import org.hibernate.Session;
 4 import org.hibernate.SessionFactory;
 5 import org.hibernate.cfg.Configuration;
 6 
 7 //工具类
 8 public class HibernateUtils {
 9 
10     private final static Configuration cfg;
11     private final static SessionFactory sessionFactory;
12     
13     //用静态代码块来实现对象只在类加载的时候创建一次(静态代码块只执行一次)
14     static{
15         //创建configuration对象,
16         cfg = new Configuration();
17         cfg.configure();
18         //根据Configuration对象创建sessionFactory对象
19         sessionFactory = cfg.buildSessionFactory();
20     }
21     
22     //返回与本地线程绑定的session
23     public static Session getSession(){
24         return sessionFactory.getCurrentSession();
25     }
26     
27     //创建一个方法用于返回sessionFactory对象
28     public static SessionFactory getSessionFactory(){
29         return sessionFactory;
30     }
31     public static void main(String[] args) {
32         
33     }
34     
35 }
HibernateUtils

在工具类中直接写一个main方法,内部不写代码,直接执行,生成user,role和关联表user-role表

 

(一:多对多级联保存)

首先在配置文件文件中的set标签上添加一个cascade属性值为save-update:在那个配置文件上添加这个属性,就保存那个对象就可以

例:将cascade属性放到user的配置文件中:

测试:

Hibernate中表与表之间的关联多对多,级联保存,级联删除Hibernate中表与表之间的关联多对多,级联保存,级联删除
 1 package com.yinfu.test;
 2 
 3 import java.util.Set;
 4 
 5 import org.hibernate.Session;
 6 import org.hibernate.SessionFactory;
 7 import org.hibernate.Transaction;
 8 import org.junit.Test;
 9 import com.yinfu.entity.Role;
10 import com.yinfu.entity.User;
11 import com.yinfu.utils.HibernateUtils;
12 
13 public class ManyToMany {
14     @Test
15     public void testAdd(){
16         SessionFactory sessionFactory = null;
17         Session session = null;
18         Transaction tx = null;
19         try {
20             sessionFactory = HibernateUtils.getSessionFactory();
21             session = sessionFactory.openSession();
22             tx = session.beginTransaction();
23             
24             //1:创建用户
25             //第一个用户
26             User user1 = new User();
27             user1.setUsername("李四");
28             user1.setPassword("12345");
29             user1.setAddress("韩国");
30             //第二个用户
31             User user2 = new User();
32             user2.setUsername("张三");
33             user2.setPassword("12345");
34             user2.setAddress("中国");
35             
36             //2:创建用角色
37             //第一个角色
38             Role role1 = new Role();
39             role1.setRole_name("经理");
40             role1.setRole_memo("经理");
41             //第二个角色
42             Role role2 = new Role();
43             role2.setRole_name("秘书");
44             role2.setRole_memo("秘书");
45             //第三个角色
46             Role role3 = new Role();
47             role3.setRole_name("保安");
48             role3.setRole_memo("保安");
49             
50             //3:建立关系,把角色放到用户里
51             //user1----role1/role2
52             user1.getSetRole().add(role1);
53             user1.getSetRole().add(role2);
54             //user2----role2/role3
55             user2.getSetRole().add(role2);
56             user2.getSetRole().add(role3);
57             
58             //保存
59             session.save(user1);
60             session.save(user2);
61             
62             tx.commit();
63         } catch (Exception e) {
64             e.printStackTrace();
65             tx.rollback();
66         }finally{
67             session.close();
68             sessionFactory.close();
69         }
70     }
71 }
test

 

(二:多对多的级联删除)

与一对一相同在相应的实体类配置文件中添加cascade属性值为delete,如果多个用逗号隔开,在那个配置文件上加的,就删除那个对象就行

测试:

Hibernate中表与表之间的关联多对多,级联保存,级联删除Hibernate中表与表之间的关联多对多,级联保存,级联删除
 1 package com.yinfu.test;
 2 
 3 import static org.junit.Assert.*;
 4 
 5 import org.hibernate.Session;
 6 import org.hibernate.SessionFactory;
 7 import org.hibernate.Transaction;
 8 import org.junit.Test;
 9 
10 import com.yinfu.entity.Customer;
11 import com.yinfu.entity.LinkMan;
12 import com.yinfu.entity.User;
13 import com.yinfu.utils.HibernateUtils;
14 
15 public class TestDelete2 {
16 
17     @Test
18     public void test() {
19         SessionFactory sessionFactory = null;
20         Session session = null;
21         Transaction tx = null;
22         try {
23             sessionFactory = HibernateUtils.getSessionFactory();
24             session = sessionFactory.openSession();
25             tx = session.beginTransaction();
26             
27             //根据ID查询User
28             User user = session.get(User.class, 6);
29             //将customer删除即可
30             session.delete(user);
31             
32             tx.commit();
33         } catch (Exception e) {
34             e.printStackTrace();
35             tx.rollback();
36         }finally{
37             session.close();
38             sessionFactory.close();
39         }
40     }
41 
42 }
test

 

(三:第三张表的维护)

让用户拥有某角色:

Hibernate中表与表之间的关联多对多,级联保存,级联删除

让用户失去某角色:

Hibernate中表与表之间的关联多对多,级联保存,级联删除