hibernate3.2(九)多对多关联映射

原作者:http://www.verydemo.com/demo_c146_i2174.html

用户和角色属于多对对关系,一个用户可以拥有多个角色,一个角色也可以属于多个用户。

public class User {
	private int userid;
	private String username;
	private Set roles;
	getter and setter..
	
}
public class Role {
	private int roleid;
	private String rolename;
                getter & setter
}

User.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.wyx.hibernate">
	<class name="User" table="t_User">
		<id name="userid">
			<generator  class="native"/>
		</id>
		<property name="username"/>
		<set name="roles" table="t_User_Role" cascade="all">
			<key column="userid" />
			<many-to-many class="Role" column="roleid"/>
		</set>
	</class>
</hibernate-mapping>

set标签中的name指的是user的关联关系字段,set代表了中间表,用table指定中间表的名字,用key 的column属性作为外键指向user表的userid,many-to-mang的column作为外键指向role表的roid,构成了复合主键(由userid和roleid构成的)。

 Role.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.wyx.hibernate">
	<class name="Role" table="t_Role">
		<id name="roleid">
			<generator class="native"/>
		</id>
		<property name="rolename"/>
	</class>
</hibernate-mapping>

 测试一对多save,从user方存储:

public void testSave(){
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			
			Role role1 = new Role();
			role1.setRolename("程序员");
			//session.save(role1);
			Role role2 = new Role();
			role2.setRolename("架构师");
			//session.save(role2);
			Set roles = new HashSet<Role>();
			roles.add(role1);
			roles.add(role2);
			
			User user =new User();
			user.setUsername("冰吼");
			user.setRoles(roles);
			session.save(user);
			session.getTransaction().commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}
		
	}

打印输出:

Hibernate: insert into t_User (username) values (?)
Hibernate: insert into t_Role (rolename) values (?)
Hibernate: insert into t_Role (rolename) values (?)
Hibernate: insert into t_User_Role (userid, roleid) values (?, ?)
Hibernate: insert into t_User_Role (userid, roleid) values (?, ?)  

 测试一对多load,从user一方存储:

public void testLoad(){
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			User user = (User)session.load(User.class, 1);
			Set<Role> roles = user.getRoles();
			System.out.println("user.username = " + user.getUsername());
			for(Iterator<Role> iter = roles.iterator(); iter.hasNext();){
				Role role = iter.next();
				System.out.println("user.role.rolename = " + role.getRolename());
			}
			session.getTransaction().commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}
		
	}

打印输出:

....................................................................

双向多对多关联映射与单向的基本一致,不同之处就是在双发都加入了set集合来保存关联关系,但是在存储字段的时候,最好指定根据一方来添加,两边都存储容易造成混乱,在其中的一方映射文件的set标签中加入inverse = "true",将控制权交给另一方处理。【inverse属性只能应用于一对多双向关联、多对多双向关联】

修改Role.java:

package com.wyx.hibernate;

import java.util.Set;

public class Role {
	private int roleid;
	private String rolename;
	private Set users;
	getter & setter...
}

 修改Role.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.wyx.hibernate">
	<class name="Role" table="t_Role">
		<id name="roleid">
			<generator class="native"/>
		</id>
		<property name="rolename"/>
		<set name="users" table="t_User_Role" inverse="true" cascade="all" order-by="userid">
			<key column="roleid"/>
			<many-to-many class="User" column="userid"/>
		</set>
	</class>
</hibernate-mapping>
                 /**
	 * save role casecad user
	 */
	public void testSave(){
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			
			User user1 =new User();
			user1.setUsername("冰吼");
			User user2 =new User();
			user2.setUsername("蓝胖");
			Set users = new HashSet<User>();
			users.add(user1);
			users.add(user2);
			
			Role role = new Role();
			role.setRolename("架构师");
			role.setUsers(users);
			session.save(role);
			
			session.getTransaction().commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}
		
	}

   

加入了inserse = "true",就不能从Role端存入数据,用以上测试方法存数据,中间表是不能存入数据的,但是去掉inserse就可以,但为了防止出错,还是加inverse由指定固定一方控制添加比较好。

猜你喜欢

转载自zxj010802986.iteye.com/blog/2073516