一个Hibernate多对多实例

这篇博客展示了如何在Hibernate中实现一个多对多的关系映射。通过一个用户与角色的经典例子,解释了User和Role的实体配置以及中间表user_role的建立。测试类演示了如何给用户分配角色,并强调了`inverse="true"`属性的作用,说明了在哪个实体维护主外键关系以及不同添加操作对SQL输出的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

更新: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语句。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值