Hibernate 多对多关系映射


一、Hibernate多对多关系映射

1.1、需求分析

示例分析

  •  我们采用的示例为用户和角色。
  •  用户:指的是系统的登录用户。
  •  角色:指的是系统不同权限的角色。
  •  用户和角色之间的关系是多对多。

1.2、多对多(多对一)表关系建立

多对多的表关系建立靠的是中间表,其中用户表和中间表的关系是一对多,角色表和中间表的关系也是一对多,如下图所示:

1.3、建立实体类关系

User实体类:一个用户可以具有多个角色,所以在用户实体类中应该包含多个角色的信息,代码如下

/**
 * 用户(多方)
 * @author lenovo
 *
 */
public class User implements Serializable{

	
	private Integer id;
	private String name;
	
	//关联角色
	private Set<Role> roles = new HashSet<Role>();
	
	
	
	public Set<Role> getRoles() {
		return roles;
	}
	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

一个角色可以赋予多个用户,所以在角色实体类中应该包含多个用户的信息,代码如下:

/**
 * 角色(多方)
 * @author lenovo
 *
 */
public class Role implements Serializable{

	private Integer id;
	private String name;
	
	//关联用户
	private Set<User> users = new HashSet<User>();
	
	
	
	public Set<User> getUsers() {
		return users;
	}
	public void setUsers(Set<User> users) {
		this.users = users;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

接下来的问题是如何通过配置的方式把实体之间的关系建立起来关系。

1.4、映射配置文件

用户配置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 package="com.yiidian.domain">
 
 	<class name="User" table="t_user">
 		<id name="id" column="id">
 			<generator class="native"></generator>
 		</id>
 		<property name="name" column="name"></property>
 		
 		<!-- 多对多映射 -->
 		<!-- 
 			table:中间表名
 		 -->
 		<set name="roles" table="t_user_role">
 			<!-- 当前方在中间表的外键 -->
 			<key column="user_id"/>
 			<!-- column:对方在中间表的外键 -->
 			<many-to-many class="Role" column="role_id"/>
 		</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 package="com.yiidian.domain">
 
 	<class name="Role" table="t_role">
 		<id name="id" column="id">
 			<generator class="native"></generator>
 		</id>
 		<property name="name" column="name"></property>
 		
 		<!-- 多对多映射 -->
 		<!-- 
 			table:中间表名
 		 -->
 		<set name="users" table="t_user_role" inverse="true">
 			<!-- 当前方在中间表的外键 -->
 			<key column="role_id"/>
 			<!-- column:对方在中间表的外键 -->
 			<many-to-many class="User" column="user_id"/>
 		</set>
 	</class>
 
</hibernate-mapping>   

1.5、hibernate.cfg.xml配置

<?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>	
	<!-- 连接数据库的参数 -->
<session-factory>
	<!-- 1.连接数据库参数 -->
	<property name="hibernate.connection.driver_class">
		com.mysql.jdbc.Driver
	</property>
	<property name="hibernate.connection.url">
		jdbc:mysql://localhost:3306/hibernate
	</property>
	<property name="hibernate.connection.username">root</property>
	<property name="hibernate.connection.password">root</property>

	<!-- hibernate方言 -->
	<property name="hibernate.dialect">
		org.hibernate.dialect.MySQLDialect
	</property>

	<!-- 2.hibernate扩展参数 -->
	<property name="hibernate.show_sql">true</property>
	<property name="hibernate.format_sql">true</property>
	<property name="hibernate.hbm2ddl.auto">update</property>

	<!-- *.hbm.xml文件 -->
	<mapping resource="com/yiidian/domain/Role.hbm.xml" />
	<mapping resource="com/yiidian/domain/User.hbm.xml" />
</session-factory>
</hibernate-configuration>	

1.6、执行多对多保存保存

/**
 * 演示Hibernate的多对多关系映射操作
 * 
 * @author http://www.yiidian.com
 * 
 */
public class Demo {

	/**
	 * 添加操作
	 */
	@Test
	public void test1(){
		/**
		 * 需求:建立2个用户,2个角色
		 */
		User u1 = new User();
		u1.setName("小苍");
		
		User u2 = new User();
		u2.setName("小泽");
		
		Role r1 = new Role();
		r1.setName("超级管理员");
		
		Role r2 = new Role();
		r2.setName("普通管理员");
		
		//建立双向关系
		u1.getRoles().add(r1);
		u1.getRoles().add(r2);
		r1.getUsers().add(u1);
		r2.getUsers().add(u1);
		
		u2.getRoles().add(r2);
		r2.getUsers().add(u2);
		
		
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		
		session.save(u1);
		session.save(u2);
		session.save(r1);
		session.save(r2);
		
		tx.commit();
		session.close();
	}

}

1.7、运行结果

控制台显示:

Hibernate: 
    insert 
    into
        t_user
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        t_user
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        t_role
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        t_role
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        t_user_role
        (user_id, role_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        t_user_role
        (user_id, role_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        t_user_role
        (user_id, role_id) 
    values
        (?, ?)

一共建立三张表,分别为t_user,t_role,t_user_role。

t_user表数据:

t_role表的数据:

t_user_role中间表的数据:

源码下载:https://pan.baidu.com/s/1miOiHWc