一個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>();
雙向多對多,上面是在user中宣告,下面是在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>();
如果單向多對多,則刪除不要的那側域宣告。比如不需要通過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語句。