阅读 45

【JPA专题】10.映射关系_多对多双向

映射关系(多对多双向)

我们使用用户和角色的多对多关系,一个用户可以拥有多个角色,一个角色可以拥有多个用户,在关系型数据库中我们使用中间表进行维护多对多的关系,本质上将其拆分成两队一对多和多对一的关系

<!-- 多对多示例 -->
<class>com.os.model.User</class>
<class>com.os.model.Role</class>
复制代码

基础关系代码:用户类

package com.os.model;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "jpa_user")
public class User {
    private Integer userId;
    private String userName;
    private String sex;

    private Set<Role> roleSet = new HashSet<>();
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }
    @Column(name = "user_name")
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
    @ManyToMany
    @JoinTable(
            name = "jpa_user_link_role",/*设置中间表的名称*/
            /*设置当前类在中间表中的外键字段名称,并且设置该外键跟哪个字段建立引用关系,默认关联主键*/
            joinColumns = {@JoinColumn(name = "fk_user_id",referencedColumnName = "id")},
            /*设置关联类在中间表的外键字段名称,并且设置该外键跟哪个字段建立引用关系,默认为主键*/
             inverseJoinColumns = {@JoinColumn(name = "fk_role_id",referencedColumnName = "id")}
    )
    public Set<Role> getRoleSet() {
        return roleSet;
    }

    public void setRoleSet(Set<Role> roleSet) {
        this.roleSet = roleSet;
    }
}
复制代码

基础关系代码:角色类

package com.os.model;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "jpg_role")
public class Role {
    private Integer roleId;
    private String roleName;

    private Set<User> userSet = new HashSet<>();

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }
    @Column(name = "role_name")
    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
    /*移交维护的权力,自己对中间表不进行维护*/
    @ManyToMany(mappedBy = "roleSet")
    public Set<User> getUserSet() {
        return userSet;
    }

    public void setUserSet(Set<User> userSet) {
        this.userSet = userSet;
    }
}
复制代码

请看代码中的注释说明,这里使用的单向关系!

1.保存操作,让角色维护关系,无法保存中间表信息

/*
    * 建立一个用户:悟空
    * 创建两个角色:CEO和CTO
    * 让角色维护关系,但是我们设置了
    * @ManyToMany(mappedBy = "roleSet")
        public Set<User> getUserSet() {
            return userSet;
        }
       查看是否中间表能存储进去
    * */
@Test
public void test01(){
    User user = new User();
    user.setUserName("悟空");
    user.setSex("男");

    Role r1 = new Role();
    r1.setRoleName("CEO");
    Role r2 = new Role();
    r2.setRoleName("CTO");

    //建立关系,让没有权力的角色维护关系
    r1.getUserSet().add(user);
    r2.getUserSet().add(user);

    //存储数据
    entityManager.persist(user);
    entityManager.persist(r1);
    entityManager.persist(r2);

}
复制代码

产生的SQL语句

Hibernate: insert into jpa_user (sex, user_name) values (?, ?)
Hibernate: insert into jpg_role (role_name) values (?)
Hibernate: insert into jpg_role (role_name) values (?)
复制代码

2.保存操作,让用户维护关系,保存中间表信息

@Test
public void test02(){
    User user = new User();
    user.setUserName("八戒");
    user.setSex("男");

    Role r1 = new Role();
    r1.setRoleName("经理");
    Role r2 = new Role();
    r2.setRoleName("主人");

    //建立关系,让用户进行维护关系
    user.getRoleSet().add(r1);
    user.getRoleSet().add(r2);

    //存储数据
    entityManager.persist(user);
    entityManager.persist(r1);
    entityManager.persist(r2);

}
复制代码

产生的SQL语句

Hibernate: insert into jpa_user (sex, user_name) values (?, ?)
Hibernate: insert into jpg_role (role_name) values (?)
Hibernate: insert into jpg_role (role_name) values (?)
Hibernate: insert into jpa_user_link_role (fk_user_id, fk_role_id) values (?, ?)
Hibernate: insert into jpa_user_link_role (fk_user_id, fk_role_id) values (?, ?)
复制代码

3.查询操作,关联对象默认使用延迟加载

@Test
public void test03(){
    User user = entityManager.find(User.class,2);
    System.out.println(user.getUserName());
    System.out.println(user.getRoleSet());
}
复制代码

产生的SQl语句

Hibernate: select user0_.id as id1_4_0_, user0_.sex as sex2_4_0_, user0_.user_name as user_nam3_4_0_ from jpa_user user0_ where user0_.id=?
八戒
Hibernate: select roleset0_.fk_user_id as fk_user_1_5_0_, roleset0_.fk_role_id as fk_role_2_5_0_, role1_.id as id1_6_1_, role1_.role_name as role_nam2_6_1_ from jpa_user_link_role roleset0_ inner join jpg_role role1_ on roleset0_.fk_role_id=role1_.id where roleset0_.fk_user_id=?
[com.os.model.Role@703feacd, com.os.model.Role@68809cc7]
复制代码

其他操作基本上是类似的!今天就到这里吧!压抑的春节。