Hibernate关系映射(七)多对多双向关联@ManyToMany Annotation方式
来源:互联网 发布:python 3.7 编辑:程序博客网 时间:2024/06/05 07:50
本篇介绍多对多的双向关联,也是Hibernate关系映射的结尾篇,后续篇章会介绍Hibernate的懒加载机制和级联相关操作。
首先还是来模拟一个实际应用的场景,在之前开发过的RBAC模型中,有这样一个关系,用户组中包含多个用户,每一个用户可以属于多个用户组,那么这就是一个多对多的关系,而我又需要从当前用户组读取到包含哪些用户,又需要从当前用户获取他在哪些组中。那么就需要建立双向关联。
Entity:UserGroup
Attr:id(Integer)
name(String)
users(Set< User >)
Entity:User
Attr:id(Integer)
name(String)
userGroups(Set< UserGroup >)
下面是数据库表结构:
可以看到,t_usergroup_user作为中间表,里面有一个字段userGroupId作为外键指向了t_usergroup表,参考了该表的id,另一个外键userId指向了t_user表,参考了该表的id。这样的结构,和单向关联没区别,下面就看实体类的书写。
import java.util.HashSet;import java.util.Set;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;import javax.persistence.Table;@Entity@Table(name="t_usergroup")public class UserGroup { private Integer id; private String name; private Set<User> users = new HashSet<User>(); public UserGroup() { super(); } public UserGroup(Integer id, String name) { super(); this.id = id; this.name = name; } @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @ManyToMany @JoinTable(name="t_usergroup_user", joinColumns={@JoinColumn(name="userGroupId")}, inverseJoinColumns={@JoinColumn(name="userId")}) public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; }}
@JoinTable(name=”t_usergroup_user”中间表的名字
joinColumns={@JoinColumn(name=”userGroupId”)},中间表参考该实体id的那个外键的名称
inverseJoinColumns={@JoinColumn(name=”userId”)})对方实体在中间表中的名称
import java.util.HashSet;import java.util.Set;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.ManyToMany;import javax.persistence.Table;@Entity@Table(name="t_user")public class User { private Integer id; private String name; private Set<UserGroup> userGroups= new HashSet<UserGroup>(); public User() { super(); } public User(Integer id, String name) { super(); this.id = id; this.name = name; } @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @ManyToMany(mappedBy="users") public Set<UserGroup> getUserGroups() { return userGroups; } public void setUserGroups(Set<UserGroup> userGroups) { this.userGroups = userGroups; }}
@ManyToMany(mappedBy=”users”)既然是双向关联,那么就要设置mappedBy属性,该属性指被UserGroup实体中的users这个属性映射。
实体类书写完毕后,我们来进行CRUD的测试
首先是添加数据的测试,testCreate()
@Test public void testCreate(){ Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); UserGroup ug1 = new UserGroup(); ug1.setName("超级管理员组"); UserGroup ug2 = new UserGroup(); ug2.setName("普通用户组"); User u1 = new User(); u1.setName("admin"); User u2 = new User(); u2.setName("wan"); Set<User> userSet1 = new HashSet<User>(); userSet1.add(u1); userSet1.add(u2); Set<User> userSet2 = new HashSet<User>(); userSet2.add(u1); //超级管理员组只有一个admin ug1.setUsers(userSet2); //普通用户组包含两个用户 ug2.setUsers(userSet1); session.saveOrUpdate(ug1); session.saveOrUpdate(ug2); session.saveOrUpdate(u1); session.saveOrUpdate(u2); session.getTransaction().commit(); }
结果:
接下来是读取操作,testRead()
@Test public void testRead(){ Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); //用户组---->用户 UserGroup ug = (UserGroup) session.load(UserGroup.class, 2); System.out.println("名称:"+ug.getName()); for(User u : ug.getUsers()){ System.out.println("包含了以下用户:"+u.getName()); } //用户---->用户组 User u = (User) session.load(User.class, 1); System.out.println("用户名称:"+u.getName()); for(UserGroup ugg : u.getUserGroups()){ System.out.println("在以下用户组中:"+ugg.getName()); } session.getTransaction().commit(); }
结果:
Hibernate: select usergroup0_.id as id6_0_, usergroup0_.name as name6_0_ from t_usergroup usergroup0_ where usergroup0_.id=?名称:普通用户组Hibernate: select users0_.userGroupId as userGrou1_1_, users0_.userId as userId1_, user1_.id as id7_0_, user1_.name as name7_0_ from t_usergroup_user users0_ left outer join t_user user1_ on users0_.userId=user1_.id where users0_.userGroupId=?包含了以下用户:admin包含了以下用户:wan用户名称:adminHibernate: select usergroups0_.userId as userId1_, usergroups0_.userGroupId as userGrou1_1_, usergroup1_.id as id6_0_, usergroup1_.name as name6_0_ from t_usergroup_user usergroups0_ left outer join t_usergroup usergroup1_ on usergroups0_.userGroupId=usergroup1_.id where usergroups0_.userId=?在以下用户组中:超级管理员组在以下用户组中:普通用户组
可以看到双向关联从哪边都可以找到另一边
接下来是修改操作,testUpdate()
@Test public void testUpdate(){ Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); UserGroup ug1 = (UserGroup) session.load(UserGroup.class, 1); ug1.setName("Super User Group"); UserGroup ug2 = (UserGroup) session.load(UserGroup.class, 2); ug2.setName("Normal User Group"); session.saveOrUpdate(ug1); session.saveOrUpdate(ug2); session.getTransaction().commit(); }
结果:
最后是删除操作,testDelete()
@Test public void testDelete(){ Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); UserGroup ug2 = (UserGroup) session.load(UserGroup.class, 2); ug2.setUsers(null); session.delete(ug2); session.getTransaction().commit(); }
结果:
Hibernate: delete from t_usergroup_user where userGroupId=?Hibernate: delete from t_usergroup where id=?
这次我们看show sql出来的语句,先删除了中间表中的关系,再删除用户组,这样的操作是对的。
那么Hibernate关系映射系列就介绍到这里,希望对你有所帮助
- Hibernate关系映射(七)多对多双向关联@ManyToMany Annotation方式
- Hibernate关系映射(六)多对多单向关联@ManyToMany Annotation方式
- hibernate关系映射--双向多对多@ManyToMany
- Hibernate关系映射(五)一对多、多对一双向关联@OneToMany @OneToMany Annotation方式
- Hibernate关系映射(三)多对一单向关联@ManyToOne Annotation方式
- Hibernate(七)实现多对多关联映射关系
- Hibernate(七)实现多对多关联映射关系
- Hibernate关系映射(11)_多对多双向关联
- Hibernate -- 映射多对多双向关联关系
- 【Hibernate四】关系映射之一对多双向关联
- hibernate 关联映射:多对一(一对多)双向关联关系
- Hibernate多对多双向关联,Annotation与映射文件方式。解决中间表无法插入数据。
- hibernate关系映射--单向多对多@ManyToMany
- Hibernate关联关系映射(多对一关联映射)
- hibernate映射一对多双向关联关系
- Hibernate关系映射(四)一对多单向关联@OneToMany Annotation方式
- Hibernate中的manytomany映射实例一(多对多双向)
- 【HIbernate框架学习】:Hibernate对象关系映射之双向多对多关联映射
- 保存app内容到手机桌面
- 对chain.doFilter(request,response)的理解
- List对象排序通用方法
- 隐藏放大缩小按钮ArcGIS API for JavaScript
- Android为什么要用xml描述界面
- Hibernate关系映射(七)多对多双向关联@ManyToMany Annotation方式
- Crazyflie笔记一:概述开发范围、工具、特点介绍
- Spring RMI实现远程调用及源码
- 网站系统分布式架构
- Ubuntu安装和查看已安装程序包
- Android ListView 几个重要属性
- (STL)std::unique函数的实现
- 100万并发连接服务器笔记之1M并发连接目标达成
- Stock (zoj 2921 贪心经典)