1. 程式人生 > >一個Hibernate多對多例項

一個Hibernate多對多例項

更新:2015-02-11

	@ManyToMany(targetEntity = Role.class, fetch = FetchType.EAGER)
	@JoinTable(name = "T_USERS_ROLES", joinColumns = @JoinColumn(name = "USER_ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
	private Set<Role> roles = new HashSet<Role>();
	@ManyToMany(mappedBy = "roles", <span style="font-family: Arial, Helvetica, sans-serif;">targetEntity = User.class , </span>fetch = FetchType.LAZY)
	private Set<User> users = new HashSet<User>();
雙向多對多,上面是在user中宣告,下面是在role中宣告。

如果單向多對多,則刪除不要的那側域宣告。比如不需要通過role去查詢擁有的user,可刪除下面role側的users域宣告
---------------------------------------------------------------------------------------------------------------------------------------------------------------

下面貼上經典的多對多例項:使用者與角色。直接上程式碼。

使用者User:

package cn.qeli.ums.entity;

import java.util.HashSet;
import java.util.Set;

public class User {

	private String userid;
	private String username;
	private String password;
	private Set roles = new HashSet();

	public User() {
		super();
	}

	public String getUserid() {
		return userid;
	}

	public void setUserid(String userid) {
		this.userid = userid;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Set getRoles() {
		return roles;
	}

	public void setRoles(Set roles) {
		this.roles = roles;
	}
}


User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC        
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"        
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="cn.qeli.ums.entity.User" table="Users">
		<id name="userid" column="userid" length="32" >
			<generator class="uuid.hex"></generator>			
		</id>
		<property name="username" length="30" />
		<property name="password" length="92" />
		<set name="roles" table="user_role">
			<key column="userid" />
			<many-to-many column="roleid" class="cn.qeli.ums.entity.Role" />
		</set>
	</class>
</hibernate-mapping>


角色Role:

package cn.qeli.ums.entity;

import java.util.HashSet;
import java.util.Set;

public class Role {

	private String roleid;
	private String rolename;
	private Integer ordernum;
	private String description;
	private Set users = new HashSet();

	public Role() {
		super();
	}

	public String getRoleid() {
		return roleid;
	}

	public void setRoleid(String roleid) {
		this.roleid = roleid;
	}

	public String getRolename() {
		return rolename;
	}

	public void setRolename(String rolename) {
		this.rolename = rolename;
	}

	public Integer getOrdernum() {
		return ordernum;
	}

	public void setOrdernum(Integer ordernum) {
		this.ordernum = ordernum;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Set getUsers() {
		return users;
	}

	public void setUsers(Set users) {
		this.users = users;
	}
}

Role.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC        
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"        
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="cn.qeli.ums.entity.Role" table="Roles">
		<id name="roleid" column="roleid" length="32" >
			<generator class="uuid.hex"></generator>			
		</id>
		<property name="rolename" length="30" />
		<property name="ordernum" />		
		<property name="description" length="200" />
		<set name="users" table="user_role" inverse="true">
			<key column="roleid"/>
			<many-to-many column="userid" class="cn.qeli.ums.entity.User" />
		</set>
	</class>
</hibernate-mapping>


測試類:在測試前假設已經存在userid為402881e7394e8f4501394e8f476d0000的使用者,存在roleid為402881e4393a6f3a01393a6f3c1a0000的角色。

package cn.qeli.ums.UTest;

import org.hibernate.Session;

import cn.qeli.ums.HibernateSessionFactory;
import cn.qeli.ums.entity.Role;
import cn.qeli.ums.entity.User;

public class UserTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		UserTest test = new UserTest();
		test.addUserToRole();
	}

	public void addUserToRole() {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		User xhg = (User) session.get("cn.qeli.ums.entity.User",
				"402881e7394e8f4501394e8f476d0000");
		Role sys = (Role) session.get("cn.qeli.ums.entity.Role",
				"402881e4393a6f3a01393a6f3c1a0000");
		xhg.getRoles().add(sys);
		session.getTransaction().commit();
	}

	public void addRole() {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		Role role = new Role();
		role.setRolename("系統管理員");
		role.setOrdernum(1);
		role.setDescription("進行系統維護的角色");
		session.save(role);
		session.getTransaction().commit();
		session.close();
	}

	public void addUser() {
		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		User user = new User();
		user.setUsername("晉江古");
		user.setPassword("1984");
		session.save(user);
		session.getTransaction().commit();
		session.close();
	}

}

執行測試類的功能,也就是給使用者賦予一個角色。會輸出以下sql語句:

select user0_.userid as userid0_0_, user0_.username as username0_0_, user0_.password as password0_0_ from Users user0_ where user0_.userid=?

select role0_.roleid as roleid2_0_, role0_.rolename as rolename2_0_, role0_.ordernum as ordernum2_0_, role0_.description as descript4_2_0_ from Roles role0_ where role0_.roleid=?

select roles0_.userid as userid0_1_, roles0_.roleid as roleid1_, role1_.roleid as roleid2_0_, role1_.rolename as rolename2_0_, role1_.ordernum as ordernum2_0_, role1_.description as descript4_2_0_ from user_role roles0_ inner join Roles role1_ on roles0_.roleid=role1_.roleid where roles0_.userid=?

insert into user_role (userid, roleid) values (?, ?)


執行後,資料庫的結果是在中間表user_role中插入一條記錄,將userid和roleid對應起來。

測試類要注意xhg.getRoles().add(sys);這行語句。細心的讀者可能會發現,這行是不是也可以用sys.getUsers().add(xhg);來代替呢?答案是不能。因為我們在Role.hbm.xml中使用了【inverse="true"】。這屬性的意思是,Role實體將不維護Role與其他實體的主外來鍵關係。此例中,就是說讓User來維護這種關係。其實不維護這種關係,說白了就是表明,凡用Role實體物件來執行set物件中的新增、更新、刪除等語句,都無效。即輸出的sql不會有最後一條insert語句。