javaEE Hibernate, 多对多关系的配置/维护

例如:User(用户)和Role(角色)是多对多的关系

Test.java:

package cn.xxx.demo;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.xxx.domain.Role;
import cn.xxx.domain.User;
import cn.xxx.utils.HibernateUtils;

//多对多关系操作
public class Test {
	@Test
	//保存员工以及角色
	public void fun1(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		//-------------------------------------------------
		//1> 创建两个 User
		User u1 = new User();
		u1.setUser_name("张三");
		
		User u2 = new User();
		u2.setUser_name("李四");
		
		//2> 创建两个 Role
		Role r1 = new Role();
		r1.setRole_name("保洁");
		
		Role r2 = new Role();
		r2.setRole_name("保安");
		//3> 用户表达关系
		u1.getRoles().add(r1);
		u1.getRoles().add(r2);
		
		u2.getRoles().add(r1);
		u2.getRoles().add(r2);
		
		//4> 角色表达关系
		//r1.getUsers().add(u1);  // 如果用户对象和角色对象都维护多对多的外键关系;那么用户和角色都表达关系会报约束异常的错误。 (角色放弃维护外键关系,则不会报错)
		//r1.getUsers().add(u2);  // 因为维护关系需要在中间表中insert插入数据;用户和角色都维护关系,会重复插入相同的外键对,造成主键约束异常。
	
		//r2.getUsers().add(u1);  // 所以在开发中,多对多关系中必须让一方放弃维护外键关系。 Role.hbm.xml配置inverse="true"
		//r2.getUsers().add(u2);
		
		//5> 调用Save方法保存
		session.save(u1);  // 将对象从瞬时状态变成持久化状态。 提交事务时,会一起保存到数据库中。
		session.save(u2);
		session.save(r1);
		session.save(r2);
		//-------------------------------------------------
		tx.commit();
		session.close();
	}
	
	@Test
	//为指定用户新增一个角色
	public void fun3(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		//-------------------------------------------------
		//1> 获得指定用户
		User user = session.get(User.class, 1l);
		//2> 创建公关角色
		Role r = new Role();
		r.setRole_name("公关");
		//3> 将角色添加到用户中
		user.getRoles().add(r);
		//4> 将角色转换为持久化
		//session.save(r);  //自动保存。 User.hbm.xml配置级联操作cascade="save-update",可以自动持久化与user对象关联的role对象。
		//-------------------------------------------------
		tx.commit();
		session.close();
	}
	
	@Test
	//为指定用户解除一个角色
	public void fun4(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		//-------------------------------------------------
		//1> 获得指定用户
		User user = session.get(User.class, 1l);
		//2> 获得要操作的角色对象(保洁,保安)
		Role r1 = session.get(Role.class, 1l);
		Role r2 = session.get(Role.class, 2l);
		//3> 将角色从用户的角色集合中移除
		user.getRoles().remove(r1);  // 多对多的关系是由用户对象维护的。 会自动更新中间表。 
		user.getRoles().remove(r2);
		
		//-------------------------------------------------
		tx.commit();
		session.close();
	}
}

User.hbm.xml(配置文件;多对多关系配置,user对象维护关系):

<?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 package="cn.xxx.domain" >
	<class name="User" table="sys_user" >
		<id name="user_id"  >
			<generator class="native"></generator>
		</id>
		<property name="user_code"  ></property>
		<property name="user_name"  ></property>
		<property name="user_password"  ></property>
		<property name="user_state"  ></property>
	
		<!-- 多对多关系表达 -->
		<!-- 
			name: 对象的属性名
			table: 多对多增加的中间表名
			key
			 |-column:外键,中间表中指向"我"的外键
			class: 与哪个类是多对多关系
			column:外键.中间表中指向"别人"的外键
		 -->
		<!-- cascade级联操作:
			save-update: 级联保存更新
			delete:级联删除
			all:级联保存更新+级联删除
			结论: cascade简化代码书写.该属性使不使用无所谓. 建议要用只用save-update.
				 如果使用delete操作太过危险.尤其在多对多中.不建议使用.
		-->
		<set name="roles" table="sys_user_role" cascade="save-update" >
			<key column="user_id" ></key>   <!-- 中间表中指向"我"的外键 -->
			<many-to-many class="Role" column="role_id" ></many-to-many>
		</set>
	
	</class>
</hibernate-mapping>

Role.hbm.xml(配置文件;多对多关系配置,role对象放弃维护关系):

<?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 package="cn.xxx.domain" >
	<class name="Role" table="sys_role" >
		<id name="role_id"  >
			<generator class="native"></generator>
		</id>
		<property name="role_name"  ></property>
		<property name="role_memo"  ></property>

		<!-- 使用inverse属性
			true: 放弃维护外键关系
			false(默认值):维护关系
			
		结论: 将来在开发中,如果遇到多对多关系.一定要选择一方放弃维护关系.
			 一般谁来放弃维护关系,要看业务方向. 例如,一般是为用户指定/解除角色,由用户维护关系.
			 那么业务方向就是由员工维护角色. 角色不需要维护与员工关系,角色放弃维护
		 -->		
		<set name="users" table="sys_user_role" inverse="true" >
			<key column="role_id" ></key>
			<many-to-many class="User" column="user_id" ></many-to-many>
		</set>
	</class>
</hibernate-mapping>

猜你喜欢

转载自blog.csdn.net/houyanhua1/article/details/81069736
今日推荐