springDataJpa联表查询之多对多

springDataJpa联表查询之多对多

场景模拟

  • 一个用户User可以有多个角色Role 一个角色可以有多个用户

分析

  • 用户表
  • 角色表
  • 用户角色中间表 userId,roleId两个字段都是外键引用

UserEntity

package cn.liyang.jpa.entity;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

/**
 * @author liyang
 * @date 2019/8/21 17:44
 * @description:
 */
@Entity
@Table(name = "sys_user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long userId;
    @Column(name = "user_name")
    private String userName;
    @Column(name = "age")
    private Integer age;
    /*
    *一个用户可以有多个角色
    *  多对多配置
    * */
    //targetEntity代表要连接的表的字节码文件
    @ManyToMany (targetEntity = Role.class)
    //用户与角色形成的中间表
    @JoinTable(name = "sys_user_role",   //中间表的名字
            //当前对象在中间表中的外键配置name : 外键在中间表中的字段名字 referencedColumnName : 引用表的字段名字
            joinColumns = {@JoinColumn(name = "sys_user_id", referencedColumnName = "user_id")} ,
            //目标链表对象的外键配置
            inverseJoinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "role_id")}
    )
    private Set roles = new HashSet<>();

    @Override
    public String toString () {
        return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", age=" + age + ", roles=" + roles + '}';
    }

    public Long getUserId () {
        return userId;
    }

    public void setUserId (Long userId) {
        this.userId = userId;
    }

    public String getUserName () {
        return userName;
    }

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

    public Integer getAge () {
        return age;
    }

    public void setAge (Integer age) {
        this.age = age;
    }

    public Set getRoles () {
        return roles;
    }

    public void setRoles (Set roles) {
        this.roles = roles;
    }
}

RoleEntity

package cn.liyang.jpa.entity;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

/**
 * @author liyang
 * @date 2019/8/21 17:31
 * @description:
 */
@Entity
@Table(name = "sye_role")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "role_id")
    private Long roleId;
    @Column(name = "role_name")
    private String name;

    public Set getUsers () {
        return users;
    }

    public void setUsers (Set users) {
        this.users = users;
    }

    //多对多表查询
    @ManyToMany(targetEntity = User.class)
    @JoinTable(name = "sys_user_role",
            joinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "role_id")},
            inverseJoinColumns = {@JoinColumn(name = "sys_user_id",referencedColumnName = "user_id")}
    )
    private Set users = new HashSet<>();

    @Override
    public String toString () {
        return "Role{" + "roleId=" + roleId + ", name='" + name + '\'' + ", users=" + users + '}';
    }

    public Long getRoleId () {
        return roleId;
    }

    public void setRoleId (Long roleId) {
        this.roleId = roleId;
    }

    public String getName () {
        return name;
    }

    public void setName (String name) {
        this.name = name;
    }
}

applicationContext.xml



    
    
        
        
        
        
    
    
    
        
        
        
        
        
        
            
                
                
                
            
        
        
            
                update
            
        
    
    
    
        
    
    
        
            
            
            
            
            
            
            
        
    
    
        
        
    
    
    


测试类ManyToMany

package cn.liyang.jpa;

import cn.liyang.jpa.dao.RoleDao;
import cn.liyang.jpa.dao.UserDao;
import cn.liyang.jpa.entity.Role;
import cn.liyang.jpa.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ManyToMany {
    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Test
    @Transactional  //开启事务
    @Rollback(false)    //拒绝回滚
    public void testAdd(){//新建角色,新建用户同时添加
        User user = new User();
        user.setAge( 18 );
        user.setUserName( "liyang02" );
        Role role = new Role();
        role.setName( "程序员02" );
        user.getRoles().add( role );
        userDao.save( user );
        roleDao.save( role );
    }
    @Test
    @Transactional  //开启事务
    @Rollback(false)    //拒绝回滚
    public void testAdd02(){//查询用户,创建一个新的角色类型,并为该用户添加这个角色
        User one = userDao.findOne( 2L );
        Role role = new Role();
        role.setName( "产品经理" );
        one.getRoles().add( role );
        roleDao.save( role );
    }
    @Test
    @Transactional  //开启事务
    @Rollback(false)    //拒绝回滚
    public void testAdd03(){//查询一条已经存在的用户和一条角色,并为该用户赋予这个角色
        Role role = roleDao.findOne( 2L );
        User user = userDao.findOne( 1L );
        user.getRoles().add( role );
    }
    @Test
    @Transactional  //开启事务
    @Rollback(false)    //拒绝回滚
    public void testAdd04(){//新建一个用户,并为该用户添加多个角色
        Role role1 = roleDao.findOne( 1L );
        Role role2 = roleDao.findOne( 2L );
        Role role3 = roleDao.findOne( 3L );
        User user = new User();
        user.setUserName( "郑愁予" );
        user.getRoles().add( role1 );
        user.getRoles().add( role2 );
        user.getRoles().add( role3 );
        userDao.save( user );//这是新建的用户记得保存
    }
}

总结

  • 核心代码,在用户Entity中建立一个角色集合,在角色Entity中建立一个用户集合

    private Set users = new HashSet<>();
    
    private Set roles = new HashSet<>();
    
  • 要创建一个中间表,表中添加外键,需要指明添加外键引用的是那一张表,哪一个字段,这些信息在集合属性注解中来完成

     /*
     *一个用户可以有多个角色
     *  多对多配置
     * */
     //targetEntity代表要连接的表的字节码文件
     @ManyToMany (targetEntity = Role.class)
     //用户与角色形成的中间表
     @JoinTable(name = "sys_user_role",   //中间表的名字
             //当前对象在中间表中的外键配置name : 外键在中间表中的字段名字 referencedColumnName : 引用表的字段名字
             joinColumns = {@JoinColumn(name = "sys_user_id", referencedColumnName = "user_id")} ,
             //目标链表对象的外键配置
             inverseJoinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "role_id")}
     )
    

你可能感兴趣的:(springDataJpa联表查询之多对多)