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关系映射系列就介绍到这里,希望对你有所帮助

0 0
原创粉丝点击