八、Hibernate映射之多对多处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mChenys/article/details/84755946

以用户和角色为例,一个用户可以有多个角色,一个角色也可以属于多个用户,这种关系刚好是多对多的关系.

创建javabean

User.java

public class User {
	private Long user_id;
	private String user_name;
	private String user_password;
	private String user_state;
	
	//多对多中关联的另一方
	private Set<Role> roles = new HashSet<Role>();
	
	//get set...
}

Role.java

public class Role {
	private Long role_id;
	private String role_name;
	
	//多对多中关联的另一方
	private Set<User> users = new HashSet<User>();

	//get set...
}

创建映射文件

User.hbm.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="blog.csdn.net.mchenys.domain.User" table="t_user">
    		
    		<id name="user_id" column="user_id">
    			<generator class="native"/>
    		</id>
    		
    		<property name="user_name" column="user_name"/>
    		<property name="user_password" column="user_password"/>
    		<property name="user_state" column="user_state"/>
    		
    		<!-- 
    		set标签属性
    			name:javabean中集合的属性名
    			table:中间表的名字,这个必现2边保持一致
    		key标签属性
    			column:中间表中对应该类的外键名	
    		many-to-many标签属性
    			class:另一方的类全路径名
    			column:另一方的类在中间表的外键名
    		 -->
    		<set name="roles" table="user_role">
    			<key column="uid"/>
    			<many-to-many class="blog.csdn.net.mchenys.domain.Role" column="rid"/>
    		</set>
    	</class>
    </hibernate-mapping>

Role.hbm.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="blog.csdn.net.mchenys.domain.Role" table="t_role">
    		
    		<id name="role_id" column="role_id">
    			<generator class="native"/>
    		</id>
    		
    		
    		<property name="role_name" column="role_name"/>
    		
    		<!-- 
    		set标签属性
    			name:javabean中集合的属性名
    			table:中间表的名字,这个必现2保持一致
    			inverse:true表示放弃维护外键,多对多关系中必须有一方放弃维护,否则会报错
    		key标签属性
    			column:中间表中对应该类的外键名	
    		many-to-many标签属性
    			class:另一方的类全路径名
    			column:另一方的类在中间表的外键名
    		 -->
    		<set name="users" table="user_role" inverse="true">
    			<key column="rid"/>
    			<many-to-many class="blog.csdn.net.mchenys.domain.User" column="uid"/>
    		</set>
    	</class>
    </hibernate-mapping>

修改核心配置文件

在核心配置文件中添加映射文件的路径

<?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>

	<!-- 记住:先配置SessionFactory标签,一个数据库对应一个SessionFactory标签 -->
	<session-factory>

		<!-- 必须要配置的参数有5个,4大参数,数据库的方言 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day03</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">1234</property>

		<!-- 数据库的方言 -->
		<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>
		<!-- 生成数据库的表结构 
			update:如果没有表结构,创建表结构。如果存在,不会创建,可动态添加字段(新增属性和映射即可),不能删除字段
		-->
		<property name="hibernate.hbm2ddl.auto">update</property>

		<!-- 开启绑定本地的session -->
		<property name="hibernate.current_session_context_class">thread</property>
		

		<!-- 映射配置文件,需要引入映射的配置文件 -->
		<mapping resource="blog/csdn/net/mchenys/domain/User.hbm.xml"/>
		<mapping resource="blog/csdn/net/mchenys/domain/Role.hbm.xml"/>
	</session-factory>

</hibernate-configuration>	

双向关联保存

/**
	 * 测试双向关联保存
	 */
	@Test
	public void test1(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction tr = session.beginTransaction();
		// 创建用户
		User u1 = new User();
		u1.setUser_name("小张");
		User u2 = new User();
		u2.setUser_name("小李");
		
		// 创建角色
		Role r1 = new Role();
		r1.setRole_name("管理员");
	
		Role r2 = new Role();
		r1.setRole_name("老师");
		
		// 双向关联
		u1.getRoles().add(r1);
		u1.getRoles().add(r2);
		r1.getUsers().add(u1);
		r2.getUsers().add(u1);
		
		u2.getRoles().add(r1);
		r1.getUsers().add(u2);
		
		session.save(u1);
		session.save(u2);
		session.save(r1);
		session.save(r2);
		
		tr.commit();
	}

级联保存

/**
	 * 级联保存:保存用户级联保存角色
	 */
	@Test
	public void test2(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction tr = session.beginTransaction();
		// 创建用户
		User u1 = new User();
		u1.setUser_name("张三");
		User u2 = new User();
		u2.setUser_name("赵四");
		
		// 创建角色
		Role r1 = new Role();
		r1.setRole_name("经理");
		Role r2 = new Role();
		r2.setRole_name("销售");
		
		//单项关联
		u1.getRoles().add(r1);
		u1.getRoles().add(r2);
		u2.getRoles().add(r1);
		
		// 级联保存数据
		session.save(u1);
		session.save(u2);
		
		tr.commit();
	}

记得要在User.hbm.xml配置文件中添加cascade属性到set标签上,例如:
在这里插入图片描述

如何修改中间表的数据

要修改中间表的数据也很简单,反应到java层面就是操作集合中的对象,只不过得先通过Hibernate先去查找出相关联的数据才能操作,下面以张三用户删除经理角色为例

/**
	 * 操作中间表数据:让张三去掉经理这角色
	 */
	@Test
	public void test3() {
		Session session = HibernateUtils.getCurrentSession();
		Transaction tr = session.beginTransaction();
		// 查找张三用户
		User user = session.get(User.class, 3L);
		// 查找经理角色
		Role role = session.get(Role.class, 4L);

		// 操作集合来解除关联,不需要执行update操作,因为持久态的对象可以有自动更新的功能
		user.getRoles().remove(role);

		// 提交
		tr.commit();
	}

猜你喜欢

转载自blog.csdn.net/mChenys/article/details/84755946