首页 > 代码库 > Hibernate 多对多
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 //得到session11 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/r239 user1.getSetRole().add(r1);40 user1.getSetRole().add(r2);41 42 // user2 -- r2/r343 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 args14 */15 @Test16 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 某个用户拥有某个角色add12 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=session.beginTransaction(); 9 10 //操作第三张表 就是让某个用户没有某个角色remove 某个用户拥有某个角色add11 12 //让1-小王佣有 2-总经理这个角色13 User xiaowang=session.get(User.class,1);14 Role role=session.get(Role.class,2);15 xiaowang.getSetrole().add(role);16 17 //提交事务18 tran.commit();19 20 }catch(Exception e){21 e.printStackTrace();22 }finally{23 } 24 }25 }
执行后
Hibernate 多对多