吴裕雄天生自然Spring Boot使用Spring Data JPA实现用户(User)与权限(Authority)的多对多关系映射

    在Spring Data JPA中使用@ManyToMany来注解多对多的映射关系,由一个关联表来维护。关联表的表名默认是:主表名+下划线+从表名(主表是指关系维护端对应的表,从表是指关系被维护端对应的表)。关联表只有两个外键字段,分别指向主表ID和从表ID。字段的名称默认为:主表名+下划线+主表中的主键列名,从表名+下划线+从表中的主键列名。需要注意的是,多对多关系中一般不设置级联保存、级联删除、级联更新等操作。
具体实现步骤如下。
1)创建持久化实体类
2)创建数据访问层
3)创建业务层
4)创建控制器类
5)运行
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.manytomany</groupId>
    <artifactId>SpringBootManytoMany</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <!-- 声明项目配置依赖编码格式为 utf-8 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <fastjson.version>1.2.24</fastjson.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 添加MySQL依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>8.0.13</version><!--$NO-MVN-MAN-VER$ -->
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
server.port=8089

server.servlet.context-path=/ch6_2
spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?serverTimezone=UTC&autoReconnect=true
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database=MYSQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jackson.serialization.indent-output=true 
package com.ch.ch6_2.entity;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@Table(name = "user")
@JsonIgnoreProperties(value = { "hibernateLazyInitializer" })
public class User implements Serializable{
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String username;
    private String password;

    @ManyToMany
    @JoinTable(name = "user_authority", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "authority_id"))
    /**
     * 1、关系维护端,负责多对多关系的绑定和解除
     * 2、@JoinTable注解的name属性指定关联表的名字,joinColumns指定外键的名字,关联到关系维护端(User)
     * 3、inverseJoinColumns指定外键的名字,要关联的关系被维护端(Authority)
     * 4、其实可以不使用@JoinTable注解,默认生成的关联表名称为主表表名+下划线+从表表名, 即表名为user_authority
     * 关联到主表的外键名:主表名+下划线+主表中的主键列名,即user_id
     * 关联到从表的外键名:主表中用于关联的属性名+下划线+从表的主键列名,即authority_id 主表就是关系维护端对应的表,从表就是关系被维护端对应的表
     */
    private List<Authority> authorityList;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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 List<Authority> getAuthorityList() {
        return authorityList;
    }

    public void setAuthorityList(List<Authority> authorityList) {
        this.authorityList = authorityList;
    }
}
package com.ch.ch6_2.entity;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@Table(name = "authority")
@JsonIgnoreProperties(value = { "hibernateLazyInitializer" })
public class Authority implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column(nullable = false)
    private String name;
    @ManyToMany(mappedBy = "authorityList")
    @JsonIgnore
    private List<User> userList;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }
}
2)创建数据访问层

在com.ch.ch6_2.repository包中,创建名为UserRepository和AuthorityRepository的接口。
package com.ch.ch6_2.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import com.ch.ch6_2.entity.User;

public interface UserRepository extends JpaRepository<User, Integer> {
    /**
     * 根据权限id查询拥有该权限的用户(关联查询) 相当于JPQL语句:select u from User u inner join
     * u.authorityList a where a.id = ?1
     */
    public List<User> findByAuthorityList_id(int id);

    /**
     * 根据权限名查询拥有该权限的用户(关联查询) 相当于JPQL语句:select u from User u inner join
     * u.authorityList a where a.name = ?1
     */
    public List<User> findByAuthorityList_name(String name);
}
package com.ch.ch6_2.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.ch.ch6_2.entity.Authority;

public interface AuthorityRepository extends JpaRepository<Authority, Integer> {
    /**
     * 根据用户id查询用户所拥有的权限(关联查询) 相当于JPQL语句:select a from Authority a inner join
     * a.userList u where u.id = ?1
     */
    public List<Authority> findByUserList_id(int id);

    /**
     * 根据用户名查询用户所拥有的权限(关联查询) 相当于JPQL语句:select a from Authority a inner join
     * a.userList u where u.username = ?1
     */
    public List<Authority> findByUserList_Username(String username);

    /**
     * 根据用户名查询用户所拥有的权限(关联查询)
     */
    @Query("select a from Authority a inner join a.userList u where u.username = ?1")
    public List<Authority> findByUserListUsername(String username);
}
3)创建业务层

在com.ch.ch6_2.service包中,创建名为UserAndAuthorityService的接口和接口实现类UserAndAuthorityServiceImpl。
package com.ch.ch6_2.service;

import java.util.List;

import com.ch.ch6_2.entity.Authority;
import com.ch.ch6_2.entity.User;

public interface UserAndAuthorityService {
    public void saveAll();

    public List<User> findByAuthorityList_id(int id);

    public List<User> findByAuthorityList_name(String name);

    public List<Authority> findByUserList_id(int id);

    public List<Authority> findByUserList_Username(String username);

    public List<Authority> findByUserListUsername(String username);
}
package com.ch.ch6_2.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ch.ch6_2.entity.Authority;
import com.ch.ch6_2.entity.User;
import com.ch.ch6_2.repository.AuthorityRepository;
import com.ch.ch6_2.repository.UserRepository;

@Service
public class UserAndAuthorityServiceImpl implements UserAndAuthorityService {
    @Autowired
    private AuthorityRepository authorityRepository;
    @Autowired
    private UserRepository userRepository;

    @Override
    public void saveAll() {
        // 添加权限1
        Authority at1 = new Authority();
        at1.setName("增加");
        authorityRepository.save(at1);
        // 添加权限2
        Authority at2 = new Authority();
        at2.setName("修改");
        authorityRepository.save(at2);
        // 添加权限3
        Authority at3 = new Authority();
        at3.setName("删除");
        authorityRepository.save(at3);
        // 添加权限4
        Authority at4 = new Authority();
        at4.setName("查询");
        authorityRepository.save(at4);
        // 添加用户1
        User u1 = new User();
        u1.setUsername("陈恒1");
        u1.setPassword("123");
        ArrayList<Authority> authorityList1 = new ArrayList<Authority>();
        authorityList1.add(at1);
        authorityList1.add(at2);
        authorityList1.add(at3);
        u1.setAuthorityList(authorityList1);
        userRepository.save(u1);
        // 添加用户2
        User u2 = new User();
        u2.setUsername("陈恒2");
        u2.setPassword("234");
        ArrayList<Authority> authorityList2 = new ArrayList<Authority>();
        authorityList2.add(at2);
        authorityList2.add(at3);
        authorityList2.add(at4);
        u2.setAuthorityList(authorityList2);
        userRepository.save(u2);
    }

    @Override
    public List<User> findByAuthorityList_id(int id) {
        return userRepository.findByAuthorityList_id(id);
    }

    @Override
    public List<User> findByAuthorityList_name(String name) {
        return userRepository.findByAuthorityList_name(name);
    }

    @Override
    public List<Authority> findByUserList_id(int id) {
        return authorityRepository.findByUserList_id(id);
    }

    @Override
    public List<Authority> findByUserList_Username(String username) {
        return authorityRepository.findByUserList_Username(username);
    }

    @Override
    public List<Authority> findByUserListUsername(String username) {
        return authorityRepository.findByUserListUsername(username);
    }
}
4)创建控制器类

在com.ch.ch6_2.controller包中,创建名为TestManyToManyController的控制器类。
package com.ch.ch6_2.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ch.ch6_2.entity.Authority;
import com.ch.ch6_2.entity.User;
import com.ch.ch6_2.service.UserAndAuthorityService;

@RestController
public class TestManyToManyController {
    @Autowired
    private UserAndAuthorityService userAndAuthorityService;

    @RequestMapping("/saveManyToMany")
    public String save() {
        userAndAuthorityService.saveAll();
        return "权限和用户保存成功!";
    }

    @RequestMapping("/findByAuthorityList_id")
    public List<User> findByAuthorityList_id(int id) {
        return userAndAuthorityService.findByAuthorityList_id(id);
    }

    @RequestMapping("/findByAuthorityList_name")
    public List<User> findByAuthorityList_name(String name) {
        return userAndAuthorityService.findByAuthorityList_name(name);
    }

    @RequestMapping("/findByUserList_id")
    public List<Authority> findByUserList_id(int id) {
        return userAndAuthorityService.findByUserList_id(id);
    }

    @RequestMapping("/findByUserList_Username")
    public List<Authority> findByUserList_Username(String username) {
        return userAndAuthorityService.findByUserList_Username(username);
    }

    @RequestMapping("/findByUserListUsername")
    public List<Authority> findByUserListUsername(String username) {
        return userAndAuthorityService.findByUserListUsername(username);
    }
}
5)运行

首先,运行Ch62Application主类。然后,访问“http://localhost:8080/ch6_2/saveManyToMany/”。

 

原文地址:https://www.cnblogs.com/tszr/p/15338343.html