Hibernate 多对多

Posted 乔克叔叔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate 多对多相关的知识,希望对你有一定的参考价值。

Hibernate多对多操作

多对多映射配置

 

以用户和角色为例演示

 

第一步 创建实体类,用户和角色

第二步 让两个实体类之间互相表示

 

(1)一个用户里面表示所有角色,使用set集合

(2)一个角色有多个用户,使用set集合

 

第三步 配置映射关系

(1)基本配置

(2)配置多对多关系

在用户里面表示所有角色,使用set标签

 在角色里面表示所有用户,使用set标签

 

两个配置文件直接设置的外键的值需要一致

第四步 在核心配置文件中引入映射文件

代码实践:

user

 1 package org.model;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class User {
 7     private Integer u_id;
 8     private String u_name;
 9     private String u_password;
10     
11     //一个用户有多个角色
12     private Set<Role> setrole=new HashSet<Role>();
13     
14     
15     public Set<Role> getSetrole() {
16         return setrole;
17     }
18     
19     public void setSetrole(Set<Role> setrole) {
20         this.setrole = setrole;
21     }
22     
23     public Integer getU_id() {
24         return u_id;
25     }
26 
27     public void setU_id(Integer uId) {
28         u_id = uId;
29     }
30 
31     public String getU_name() {
32         return u_name;
33     }
34     public void setU_name(String uName) {
35         u_name = uName;
36     }
37     public String getU_password() {
38         return u_password;
39     }
40     public void setU_password(String uPassword) {
41         u_password = uPassword;
42     }
43 }

Role

 1 package org.model;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class Role {
 7     private Integer r_id;
 8     private String r_name;
 9     private String r_memo;//角色介绍
10     
11     //一个角色可以有多个用户
12     private Set<User> setuser=new HashSet<User>();
13     
14     
15     public Set<User> getSetuser() {
16         return setuser;
17     }
18     public void setSetuser(Set<User> setuser) {
19         this.setuser = setuser;
20     }
21     
22     public Integer getR_id() {
23         return r_id;
24     }
25     public void setR_id(Integer rId) {
26         r_id = rId;
27     }
28     public String getR_name() {
29         return r_name;
30     }
31     public void setR_name(String rName) {
32         r_name = rName;
33     }
34     public String getR_memo() {
35         return r_memo;
36     }
37     public void setR_memo(String rMemo) {
38         r_memo = rMemo;
39     }
40 }

 

User.hbm.xm

 

 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="org.model.User" table="t_User">
 7             <id name="u_id" column="u_id">
 8                 <generator class="native"></generator>
 9             </id>
10             <property name="u_name" column="u_name"></property>
11             <property name="u_password" column="u_password"></property>
12             <!-- name属性 是本配置文件对应的实体类中的set属性值 table属性 是第三张表的名字 -->
13             <set name="setrole" table="user_role">
14                 <!-- column属性 是第三章表中生成的外键的名称  可以随便写  -->
15                 <key column="uid"></key>
16                 <!-- class属性 是role实体类的全路径 column属性  是第三章表中生成的外键的名称-->
17                 <many-to-many class="org.model.Role" column="rid"></many-to-many>
18             </set>
19         </class>
20     </hibernate-mapping>

 

Role.hbm.xml

 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="org.model.Role" table="t_Role">
 7             <id name="r_id" column="r_id">
 8                 <generator class="native"></generator>
 9             </id>
10             <property name="r_name" column="r_name"></property>
11             <property name="r_memo" column="r_memo"></property>
12             <set name="setuser" table="user_role">
13                 <key column="rid"></key>
14                 <many-to-many class="org.model.User" column="uid"></many-to-many>
15             </set>
16         </class>
17     </hibernate-mapping>

 

hibernate.cfg.xml

 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     <session-factory>
 7         <!-- 第一步:配置数据库信息 -->
 8         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
 9         <property name="hibernate.connection.username">root</property>
10         <property name="hibernate.connection.password">jay571018</property>
11         <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate3_demo2</property>
12         <!-- 第二步:配置Hibernate信息 -->
13         <property name="hibernate.show_sql">true</property>
14         <property name="hibernate.format_sql">true</property>
15         <!-- 自动建表 -->
16         <property name="hibernate.hbm2ddl.auto">update</property>
17         <!-- 设置数据库方言 -->
18         <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
19         <!-- 设置与本地线程绑定session -->
20         <property name="hibernate.current_session_context_class">thread</property>
21         
22         <!-- 第三步:引入对象关系映射文件 -->
23         <mapping resource="org/model/Role.hbm.xml"/>
24         <mapping resource="org/model/User.hbm.xml"/>
25     </session-factory>
26 </hibernate-configuration>

 

sessionFactoryutils.java

 1 package org.util;
 2 
 3 import org.hibernate.Session;
 4 import org.hibernate.SessionFactory;
 5 import org.hibernate.cfg.Configuration;
 6 
 7 public class SessionFactoryUtils {
 8      static Configuration configuration=null;
 9      static SessionFactory sf=null;
10     
11     static{
12         configuration=new Configuration();
13         configuration.configure();//加载核心配置文件
14         sf=configuration.buildSessionFactory();
15     }
16     public static Session get(){
17         return sf.getCurrentSession();
18     }
19     
20     public static void main(String[] args){21     }
22     
23 }

执行工具类的代码,然后就会自动建立表

多对多级联保存

 

根据用户保存角色

第一步 在用户配置文件中set标签进行配置,cascade值save-update

第二步 写代码实现

(1)创建用户和角色对象,把角色放到用户里面,最终保存用户就可以了

 1 //演示多对多修级联保存
 2     @Test
 3     public void testSave() {
 4         SessionFactory sessionFactory = null;
 5         Session session = null;
 6         Transaction tx = null;
 7         try {
 8             //得到sessionFactory
 9             sessionFactory = HibernateUtils.getSessionFactory();
10             //得到session
11             session = sessionFactory.openSession();
12             //开启事务
13             tx = session.beginTransaction();
14             
15             //添加两个用户,为每个用户添加两个角色
16             //1 创建对象
17             User user1 = new User();
18             user1.setUser_name("lucy");
19             user1.setUser_password("123");
20             
21             User user2 = new User();
22             user2.setUser_name("mary");
23             user2.setUser_password("456");
24             
25             Role r1 = new Role();
26             r1.setRole_name("总经理");
27             r1.setRole_memo("总经理");
28             
29             Role r2 = new Role();
30             r2.setRole_name("秘书");
31             r2.setRole_memo("秘书");
32             
33             Role r3 = new Role();
34             r3.setRole_name("保安");
35             r3.setRole_memo("保安");
36             
37             //2 建立关系,把角色放到用户里面
38             // user1 -- r1/r2
39             user1.getSetRole().add(r1);
40             user1.getSetRole().add(r2);
41             
42             // user2 -- r2/r3
43             user2.getSetRole().add(r2);
44             user2.getSetRole().add(r3);
45             
46             //3 保存用户
47             session.save(user1);
48             session.save(user2);
49             
50             //提交事务
51             tx.commit();
52 
53         }catch(Exception e) {
54             tx.rollback();
55         }finally {
56             session.close();
57             //sessionFactory不需要关闭
58             sessionFactory.close();
59         }
60     }

代码实践:

user.hbm.xml

 

 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="org.model.User" table="t_User">
 7             <id name="u_id" column="u_id">
 8                 <generator class="native"></generator>
 9             </id>
10             <property name="u_name" column="u_name"></property>
11             <property name="u_password" column="u_password"></property>
12             <!-- name属性 是本配置文件对应的实体类中的set属性值 table属性 是第三张表的名字 -->
13             <set name="setrole" table="user_role" cascade="save-update">
14                 <!-- column属性 是第三章表中生成的外键的名称  可以随便写  -->
15                 <key column="uid"></key>
16                 <!-- class属性 是role实体类的全路径 column属性  是第三章表中生成的外键的名称-->
17                 <many-to-many class="org.model.Role" column="rid"></many-to-many>
18             </set>
19         </class>
20     </hibernate-mapping>

 

测试类

 

 1 package org.testdemo;
 2 
 3 import org.hibernate.Session;
 4 import org.hibernate.Transaction;
 5 import org.junit.Test;
 6 import org.model.Role;
 7 import org.model.User;
 8 import org.util.SessionFactoryUtils;
 9 
10 public class testDemo {
11 
12     /**
13      * @param args
14      */
15     @Test
16     public void test(){
17         Session session=null;
18         Transaction tran=null;
19         try{
20             session=SessionFactoryUtils.get();
21             //开启事务
22             tran=session.beginTransaction();
23             //创建两个用户
24             User user1=new User();
25             User user2=new User();
26             user1.setU_name("小王");
27             user1.setU_password("123");
28             user2.setU_name("小红");
29             user2.setU_password("456");
30             //创建3个角色
31             Role role1=new Role();
32             Role role2=new Role();
33             Role role3=new Role();
34             role1.setR_name("总经理");
35             role1.setR_memo("总经理");
36             role2.setR_name("秘书");
37             role2.setR_memo("秘书");
38             role3.setR_name("清洁工");
39             role3.setR_memo("清洁工");
40             
41             //建立关系  因为在user配置文件中 set标签内 已经配置了cascade属性  所以  这里只需要保存user就可实现级联保存
42             //否则 还需要在user中添加role  role中添加user才能实现功能  这就是级联的优点
43             //假设user1有role1,role2两个角色
44             //假设user2有role2,role3两个角色
45             user1.getSetrole().add(role1);
46             user1.getSetrole().add(role2);
47             user2.getSetrole().add(role2);
48             user2.getSetrole().add(role3);
49             //进行保存
50             session.save(user1);
51             session.save(user2);
52             //提交事务
53             tran.commit();
54             
55         }catch(Exception e){
56             e.printStackTrace();
57         }finally{
58         }
59     }
60 
61 }

 

执行之后的结果:

 

多对多级联删除(了解)

 

第一步 在set标签进行配置,cascade值delete

第二步 删除用户

 

代码实践:

user.hbm.xml

 

 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="org.model.User" table="t_User">
 7             <id name="u_id" column="u_id">
 8                 <generator class="native"></generator>
 9             </id>
10             <property name="u_name" column="u_name"></property>
11             <property name="u_password" column="u_password"></property>
12             <!-- name属性 是本配置文件对应的实体类中的set属性值 table属性 是第三张表的名字 -->
13             <set name="setrole" table="user_role" cascade="save-update,delete">
14                 <!-- column属性 是第三章表中生成的外键的名称  可以随便写  -->
15                 <key column="uid"></key>
16                 <!-- class属性 是role实体类的全路径 column属性  是第三章表中生成的外键的名称-->
17                 <many-to-many class="org.model.Role" column="rid"></many-to-many>
18             </set>
19         </class>
20     </hibernate-mapping>

 

测试代码:

 

 1 public void testdelete(){
 2         //测试级联删除
 3         Session session=null;
 4         Transaction tran=null;
 5         try{
 6             session=SessionFactoryUtils.get();
 7             //开启事务
 8             tran=session.beginTransaction();
 9             
10             User user=session.get(User.class,1);
11             session.delete(user);
12             //提交事务
13             tran.commit();
14             
15         }catch(Exception e){
16             e.printStackTrace();
17         }finally{
18         }
19         
20     }

执行之后:

可以看到使用级联删除时 有关id为1的对象的数据全部都删除了  所以我们一般不使用级联删除

不使用级联删除测试:

User.hbm.xml 

 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="org.model.User" table="t_User">
 7             <id name="u_id" column="u_id">
 8                 <generator class="native"></generator>
 9             </id>
10             <property name="u_name" column="u_name"></property>
11             <property name="u_password" column="u_password"></property>
12             <!-- name属性 是本配置文件对应的实体类中的set属性值 table属性 是第三张表的名字 -->
13             <set name="setrole" table="user_role" cascade="save-update">
14                 <!-- column属性 是第三章表中生成的外键的名称  可以随便写  -->
15                 <key column="uid"></key>
16                 <!-- class属性 是role实体类的全路径 column属性  是第三章表中生成的外键的名称-->
17                 <many-to-many class="org.model.Role" column="rid"></many-to-many>
18             </set>
19         </class>
20     </hibernate-mapping>

测试代码不变,执行之后的结果:

只删除了id为1的记录,这个一般是我们需要的删除结果

 

维护第三张表关系

 操作第三张表  就是让某个用户没有某个角色remove 某个用户拥有某个角色add

1 用户和角色多对多关系,维护关系通过第三张表维护

2 让某个用户有某个角色

第一步 根据id查询用户和角色

第二步 把角色放到用户里面

(1)把角色对象放到用户set集合

 

3 让某个用户没有某个角色

第一步 根据id查询用户和角色

第二步 从用户里面把角色去掉

(1)从set集合里面把角色移除

代码实践:

让1-小王没有 2-总经理这个角色

操作前:

 

 

测试代码:

 1     @Test
 2     public void testremove(){
 3         
 4         Session session=null;
 5         Transaction tran=null;
 6         try{
 7             session=SessionFactoryUtils.get();
 8             //开启事务
 9             tran=session.beginTransaction();
10             
11             //操作第三张表  就是让某个用户没有某个角色remove 某个用户拥有某个角色add
12             
13             //让1-小王没有 2-总经理这个角色
14             //先得到对象的对象
15             User xiaowang=session.get(User.class,1);
16             Role role=session.get(Role.class,2);
17             xiaowang.getSetrole().remove(role);
18             //因为是持久态对象  所以无需保存  提交事务之后 自动会进行表的更新
19             
20 
21             //提交事务
22             tran.commit();
23             
24         }catch(Exception e){
25             e.printStackTrace();
26         }finally{
27         }    
28     }

 

执行后

让1-小王重新拥有 2-总经理这个角色

操作前

 

测试代码: 

 1 @Test
 2     public void testadd(){
 3         Session session=null;
 4         Transaction tran=null;
 5         try{
 6             session=SessionFactoryUtils.get();
 7             //开启事务
 8             tran=Hibernate 单向/双向 多对多

Hibernate学习8—Hibernate 映射关系(多对多)

Hibernate多对多关系

hibernate多对多查询

Hibernate-ORM:12.Hibernate中的多对多关联关系

Hibernate多对多关系映射(建表)