更新: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 roles = new HashSet();
@ManyToMany(mappedBy = "roles", targetEntity = User.class , fetch = FetchType.LAZY)
private Set users = new HashSet();
双向多对多,上面是在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
角色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
测试类:在测试前假设已经存在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语句。