Spring Boot---(9)SpringBoot整合JPA(实现核心接口以及一对多,多对多)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1021979964/article/details/88760928

SpringBoot整合JPA

Spring Data:

Spring Data是Spring提供了一个操作数据的框架。而Spring Data Jpa只是Spring Data框架下的一个基于JPA标准操作数据的模块。

Spring Data JPA:

基于JPA的标准对数据进行操作。简化操作持久层的代码。只需要编写接口就可以了。

Spring Data JPA提供的核心接口:

1.Repository接口
  提供方法名称命名查询方式
  提供基于@Query注解查询与更新
2.CrudRepository接口
  继承Repository接口,实现CRUD相关操作
3.PagingAndSortingRepository接口
  继承CrudRepository接口,实现分页排序相关操作
4.JpaRepository接口
  继承PagingAndSortingRepository接口,实现JPA规范相关操作
5.JPASpecificationExecutor接口
  不属于Repository体系,单独存在,提供多条件的支持,并且可以在查询中添加分页和排序

直接写案例测试这五个接口

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>spring-boot-kevin</artifactId>
        <groupId>com.kevin</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>08-spring-boot-jpa</artifactId>

    <dependencies>
        <!-- springBoot的启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- thymeleaf的启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- springboot整合jpa需要的依赖包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- druid连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>

        <!-- 测试工具的启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>


    </dependencies>

</project>

application.yml

spring:
  #配置数据源
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_crud?characterEncoding=utf-8
    username: root
    password: 123456
    #使用druid连接池
    type: com.alibaba.druid.pool.DruidDataSource
  jpa:
    hibernate:
      #正向工程,如果数据中没有表,则会创建一张表再更新数据,存在,则会直接更新数据
      ddl-auto: update
    #打印执行sql语句
    show-sql: true

启动类

package com.kevin;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

/**
 * @author kevin
 * @version 1.0
 * @description     SpringBoot整合JPA
 *      Spring Data:Spring Data是Spring提供了一个操作数据的框架。而Spring Data Jpa只是Spring Data框架下的一个基于JPA标准操作数据的模块。
 *      Spring Data JPA:基于JPA的标准对数据进行操作。简化操作持久层的代码。只需要编写接口就可以了。
 *
 *   Spring Data JPA提供的核心接口:
 *      1.Repository接口
 *          提供方法名称命名查询方式
 *          提供基于@Query注解查询与更新
 *      2.CrudRepository接口
 *          继承Repository接口,实现CRUD相关操作
 *      3.PagingAndSortingRepository接口
 *          继承CrudRepository接口,实现分页排序相关操作
 *      4.JpaRepository接口
 *          继承PagingAndSortingRepository接口,实现JPA规范相关操作
 *      5.JPASpecificationExecutor接口
 *          不属于Repository体系,单独存在,提供多条件的支持,并且可以在查询中添加分页和排序
 *
 * @createDate 2019/3/20
 */
@SpringBootApplication
@EnableJpaRepositories(basePackages = "com.kevin.dao")
public class JpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(JpaApplication.class,args);
    }
}

Users用户实体类

package com.kevin.entity;

import javax.persistence.*;

/**
 * @author kevin
 * @version 1.0
 * @description     用户实体类
 * @createDate 2019/3/20
 */
@Entity     // 表示该类为实体类
@Table(name="t_users")      // 对应数据库中的表名
public class Users {

    @Id     // 表示为主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)     // 该主键的策略
    @Column(name = "id")        // 列名
    private Integer id;
    @Column(name = "name")      // 列名
    private String name;
    @Column(name = "age")       // 列名
    private Integer age;
    @Column(name = "address")   // 列名
    private String address;

    @ManyToOne(cascade = CascadeType.PERSIST)      // ManyToOne表示多对一,cascade = CascadeType.PERSIST属性是级联操作
    @JoinColumn(name = "roles_id")   // 维护外键
    private Roles roles;        // 对应的角色

    public Users() {
    }

    public Users(String name, Integer age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    public String toString() {
        return "Users{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }

    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;
    }

    public Integer getAge() {
        return age;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Roles getRoles() {
        return roles;
    }

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

Roles角色实体类

package com.kevin.entity;

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

/**
 * @author kevin
 * @version 1.0
 * @description     角色实体类
 *      一对多
 *      一个角色对应多个用户
 * @createDate 2019/3/21
 */
@Entity
@Table(name = "t_roles")
public class Roles {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="roleid")
    private Integer roleid;

    @Column(name="rolename")
    private String rolename;

    @OneToMany(mappedBy = "roles")  // 一对多
    private Set<Users> users = new HashSet<>();     // 多个用户

    // cascade = CascadeType.PERSIST:开启级联操作。fetch = FetchType.EAGER:设置为立即加载。
    @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)         // 多对多
    // @JoinTable:映射中间表信息,name:中间表的表名,joinColumns:当前表中的主键所关联的中间表中的外键
    @JoinTable(name = "t_roles_menus", joinColumns = @JoinColumn(name = "role_id"),inverseJoinColumns = @JoinColumn(name = "menus_id"))
    private Set<Menus> menus = new HashSet<>();

    public Integer getRoleid() {
        return roleid;
    }

    public void setRoleid(Integer roleid) {
        this.roleid = roleid;
    }

    public String getRolename() {
        return rolename;
    }

    public void setRolename(String rolename) {
        this.rolename = rolename;
    }

    public Set<Users> getUsers() {
        return users;
    }

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

    public Set<Menus> getMenus() {
        return menus;
    }

    public void setMenus(Set<Menus> menus) {
        this.menus = menus;
    }

    @Override
    public String toString() {
        return "Roles{" +
                "roleid=" + roleid +
                ", rolename='" + rolename + '\'' +
                ", users=" + users +
                ", menus=" + menus +
                '}';
    }
}

Menus菜单实体类

package com.kevin.entity;

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

/**
 * @author kevin
 * @version 1.0
 * @description     菜单表
 *      多对多
 *      多个菜单对应多个角色
 * @createDate 2019/3/21
 */
@Entity
@Table(name = "t_menus")
public class Menus {

    @Id     // 表示主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)     // 主键规则
    @Column(name = "menusid")   // 列名
    private Integer menusid;

    @Column(name = "menusname")
    private String menusname;

    @Column(name = "menusurl")
    private String menusurl;

    @Column(name = "fatherid")
    private Integer fatherid;

    @ManyToMany(mappedBy = "menus")     // 多对多,mappedBy:Roles中关联的字段名称
    private Set<Roles> roles = new HashSet<>();

    public Integer getMenusid() {
        return menusid;
    }

    public void setMenusid(Integer menusid) {
        this.menusid = menusid;
    }

    public String getMenusname() {
        return menusname;
    }

    public void setMenusname(String menusname) {
        this.menusname = menusname;
    }

    public String getMenusurl() {
        return menusurl;
    }

    public void setMenusurl(String menusurl) {
        this.menusurl = menusurl;
    }

    public Integer getFatherid() {
        return fatherid;
    }

    public void setFatherid(Integer fatherid) {
        this.fatherid = fatherid;
    }

    public Set<Roles> getRoles() {
        return roles;
    }

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

    @Override
    public String toString() {
        return "Menus{" +
                "menusid=" + menusid +
                ", menusname='" + menusname + '\'' +
                ", menusurl='" + menusurl + '\'' +
                ", fatherid=" + fatherid +
                '}';
    }
}

1.Repository接口方法命名查询

package com.kevin.dao;

import com.kevin.entity.Users;
import org.springframework.data.repository.Repository;

import java.util.List;

/**
 * @author kevin
 * @version 1.0
 * @description     Repository接口的使用:方法名称命名查询的使用
 * @createDate 2019/3/20
 */
public interface UsersRepositoryByName extends Repository<Users,Integer> {

    // 方法命名规则:必须要遵循驼峰式命名规则。findBy(关键字)+属性名称(首字母要大写)+查询条件(首字母要大写)
    // 根据名字查询
    List<Users> findByName(String name);

    // 根据名字和年龄查询
    List<Users> findByNameAndAge(String name,Integer age);

    // 根据名字用通配符做查询
    List<Users> findByNameLike(String name);
}

1.Repository接口中@Query

package com.kevin.dao;

import com.kevin.entity.Users;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author kevin
 * @version 1.0
 * @description     Repository接口的使用:@Query的使用
 *
 * @createDate 2019/3/20
 */
@Transactional
public interface UsersRepositoryQueryAnnotation extends Repository<Users, Integer> {

    // @Query查询
    // @Query 以对象HQL语句查询。根据名字作为条件查询
    @Query("from Users where name = :name")
    List<Users> queryByNameUseHQL(@Param("name") String name);

    // @Query 以对象SQL语句查询。根据名字作为条件查询,使用标准的SQL
    @Query(value="select * from t_users where name = ? ",nativeQuery = true)
    List<Users> queryByNameUseSQL(String name);

    // @Query更新
    // @Query根据id更新name
    @Query("update Users set name = :name where id = :id")
    @Modifying
    void updateUsersNameById(@Param("name")String name, @Param("id") Integer id);


}

2.CrudRepository接口的使用

package com.kevin.dao;

import com.kevin.entity.Users;
import org.springframework.data.repository.CrudRepository;

/**
 * @author kevin
 * @version 1.0
 * @description     CrudRepository接口的使用:主要是完成一些增删改查的操作。
 *      CrudRepository接口继承了Repository接口
 * @createDate 2019/3/20
 */
public interface UsersCrudRepository extends CrudRepository<Users,Integer> {

}

3.PagingAndSortRepository接口的使用

package com.kevin.dao;

import com.kevin.entity.Users;
import org.springframework.data.repository.PagingAndSortingRepository;

/**
 * @author kevin
 * @version 1.0
 * @description     PagingAndSortingRepository的使用。主要是排序,分页等
 * @createDate 2019/3/20
 */
public interface UsersPagingAndSortingRepository extends PagingAndSortingRepository<Users,Integer> {

}

4.JPARepository接口在Users的使用

package com.kevin.dao;

import com.kevin.entity.Users;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * @author kevin
 * @version 1.0
 * @description         JpaRepository接口的使用,对继承的父接口中的方法的返回值进行适配。
 *      参数一 T :当前需要映射的实体类
 *      参数二 ID :当前映射的实体类中的OID的类型
 * @createDate 2019/3/20
 */
public interface UsersJpaRepository extends JpaRepository<Users,Integer> {

}

4.JPARepository接口在Roles的使用

package com.kevin.dao;

import com.kevin.entity.Roles;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * @author kevin
 * @version 1.0
 * @description     操作Roles表
 * @createDate 2019/3/21
 */
public interface RolesJpaRepository extends JpaRepository<Roles,Integer> {

}

5.JpaSpecificationExecutor接口的使用

package com.kevin.dao;

import com.kevin.entity.Users;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/**
 * @author kevin
 * @version 1.0
 * @description     JpaSpecificationExecutor的使用,提供多条件的支持,并且可以在查询中添加分页和排序
 * @createDate 2019/3/21
 */
public interface UsersJpaSpecificationExecutor extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users> {
}

以下的测试方法使用了SpringBoot中的Test

 

测试Repository中方法名称查询和@Query

package com.kevin.test;

import com.kevin.JpaApplication;
import com.kevin.dao.UsersJpaRepository;
import com.kevin.dao.UsersRepositoryByName;
import com.kevin.dao.UsersRepositoryQueryAnnotation;
import com.kevin.entity.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author kevin
 * @version 1.0
 * @description     测试Repository功能,方法名称命名与@Quert功能
 * @createDate 2019/3/20
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersRepositoryTest {

    @Autowired
    private UsersRepositoryByName usersRepositoryByName;

    @Autowired
    private UsersRepositoryQueryAnnotation usersRepositoryQueryAnnotation;

    // Repository---方法名称命名测试,根据名字作为条件查询
    @Test
    public void testFindByName(){

        List<Users> list  = this.usersRepositoryByName.findByName("kevin");
        for (Users user : list) {
            System.out.println(user.toString());
        }
    }

    // Repository---方法名称命名测试,根据名字和年龄作为条件查询
    @Test
    public void testFindByNameAndAge(){

        List<Users> list  = this.usersRepositoryByName.findByNameAndAge("kevin",22);
        for (Users user : list) {
            System.out.println(user.toString());
        }
    }

    // Repository---方法名称命名测试,根据名字做通配符查询
    @Test
    public void testFindByNameLike(){

        List<Users> list  = this.usersRepositoryByName.findByNameLike("co%");
        for (Users user : list) {
            System.out.println(user.toString());
        }
    }

    // Repository---@Quert测试,根据名字查询HQL
    @Test
    public void testQueryByNameUseHQL(){

        List<Users> list  = this.usersRepositoryQueryAnnotation.queryByNameUseHQL("coco");
        for (Users user : list) {
            System.out.println(user.toString());
        }
    }

    // Repository---@Quert测试,根据名字查询SQL
    @Test
    public void testQueryByNameUseSQL(){

        List<Users> list  = this.usersRepositoryQueryAnnotation.queryByNameUseSQL("kevin");
        for (Users user : list) {
            System.out.println(user.toString());
        }
    }

    // Repository---@Quert测试,根据id更新name
    @Test
    @Transactional      //@Transactional与@Test一起使用时,会自动回滚
    @Rollback(false)        // 取消自动回滚
    public void testUpdateUsersNameById(){

        this.usersRepositoryQueryAnnotation.updateUsersNameById("tomcat",1);

    }


}

测试CrudRepository接口

package com.kevin.test;

import com.kevin.JpaApplication;
import com.kevin.dao.UsersCrudRepository;
import com.kevin.entity.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
 * @author kevin
 * @version 1.0
 * @description        测试CrudRepository,增删改查功能
 * @createDate 2019/3/20
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersCrudRepositoryTest {

    @Autowired
    private UsersCrudRepository usersCrudRepository;


    // CrudRepository测试,新增功能
    @Test
    public void testCrudRepositorySave(){
        Users user = new Users();
        user.setAddress("上海");
        user.setAge(22);
        user.setName("java");
        this.usersCrudRepository.save(user);
    }

    // CrudRepository测试,更新功能,save方法即是插入又是更新
    @Test
    public void testCrudRepositoryUpdate(){
        Users user = new Users();
        user.setAddress("上海");
        user.setAge(22);
        user.setName("scala");
        user.setId(4);
        this.usersCrudRepository.save(user);
    }

    // CrudRepository测试,查询功能,根据id查询
    @Test
    public void testCrudRepositoryFindById(){
        Users user = this.usersCrudRepository.findById(1).get();
        System.out.println(user.toString());
    }

    // CrudRepository测试,查询功能,查询全部
    @Test
    public void testCrudRepositoryFindAll(){

        List<Users> users = (List<Users>) this.usersCrudRepository.findAll();
        for (Users user:users) {
            System.out.println(user);
        }
    }

    // CrudRepository测试,删除功能,根据id删除
    @Test
    public void testCrudRepositoryDeleteById(){

        this.usersCrudRepository.deleteById(5);
    }

}

测试PagingAndSortingRepository接口

package com.kevin.test;

import com.kevin.JpaApplication;
import com.kevin.dao.UsersPagingAndSortingRepository;
import com.kevin.entity.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;

import java.util.List;

/**
 * @author kevin
 * @version 1.0
 * @description     测试PagingAndSortRepository排序与分页功能
 * @createDate 2019/3/20
 */

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersPagingAndSortingRepositoryTest {

    @Autowired
    private UsersPagingAndSortingRepository usersRepositoryPagingAndSorting;


    // PagingAndSortingRepository      排序功能
    @Test
    public void testPagingAndSortingRepositorySort(){
        // Order定义排序规则。降序
        Order order = new Order(Direction.DESC,"id");
        //Sort对象封装了排序规则
        Sort sort = new Sort(order);
        List<Users> list = (List<Users>)this.usersRepositoryPagingAndSorting.findAll(sort);
        for (Users user:list) {
            System.out.println(user.toString());
        }
    }

    // PagingAndSortingRepository      分页功能
    @Test
    public void testPagingAndSortingRepositoryPaging(){
        // Pageable:封装了分页的参数,当前页,每页显示的条数。注意:它的当前页从0开始
        // PageRequest(page,size)page:当前页。size:每页显示的条数
        Pageable pageable = new PageRequest(0,2);

        Page<Users> list = this.usersRepositoryPagingAndSorting.findAll(pageable);
        System.out.println("总条数:"+list.getTotalElements());
        System.out.println("总页数:"+list.getTotalPages());

        for (Users user:list) {
            System.out.println(user.toString());
        }
    }

    // PagingAndSortingRepository      排序+分页功能
    @Test
    public void testPagingAndSortingRepositorySortAndPaging(){

        // 根据id进行升序排序
        Sort sort = new Sort(new Order(Direction.ASC,"id"));
        // 根据0开始显示两条数据,并排序
        Pageable pageable = new PageRequest(0,2,sort);

        Page<Users> list = this.usersRepositoryPagingAndSorting.findAll(pageable);
        System.out.println("总条数:"+list.getTotalElements());
        System.out.println("总页数:"+list.getTotalPages());

        for (Users user:list) {
            System.out.println(user.toString());
        }
    }



}

测试JPARepository接口

package com.kevin.test;

import com.kevin.JpaApplication;
import com.kevin.entity.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
 * @author kevin
 * @version 1.0
 * @description         测试JpaRepository,具体功能最多
 * @createDate 2019/3/21
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersJpaRepositoryTest {

    @Autowired
    private com.kevin.dao.UsersJpaRepository usersJpaRepository;

    // JpaRepository   新增或更新功能,save方法会判断,如果数据库没有该条数据则插入,存在则更新
    @Test
    public void testSave(){
        Users users = new Users();
        users.setAddress("广州");
        users.setAge(22);
        users.setName("cnq");
        this.usersJpaRepository.save(users);
    }

    // JpaRepository    查询功能,根据id查询
    @Test
    public void testFindById(){
        Users user = this.usersJpaRepository.findById(1).get();
        System.out.println(user);
    }

    // JpaRepository    查询功能,查询全部
    @Test
    public void testFindAll(){
        List<Users> list = this.usersJpaRepository.findAll();
        for (Users user:list) {
            System.out.println(user);
        }
    }

    // JpaRepository    删除功能,根据id查询
    @Test
    public void testDeleteById(){
        this.usersJpaRepository.deleteById(6);
    }

    // JpaRepository    删除功能,根据对象删除
    @Test
    public void testDelete(){
        Users users = new Users();
        users.setAddress("广州");
        users.setAge(22);
        users.setName("cnq");
        users.setId(6);
        this.usersJpaRepository.delete(users);
    }




}

测试JpaSpecificationExcutor接口

package com.kevin.test;

import com.kevin.JpaApplication;
import com.kevin.dao.UsersJpaSpecificationExecutor;
import com.kevin.entity.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * @author kevin
 * @version 1.0
 * @description     测试JpaSpecificationExecutor功能,多条件查询
 * @createDate 2019/3/21
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersJpaSpecificationExecutorTest {

    @Autowired
    private UsersJpaSpecificationExecutor usersJpaSpecificationExecutor;

    // JpaSpecificationExecutor   单条件查询
    @Test
    public void testJpaSpecificationExecutor1(){

        // Specification<Users>:用于封装查询条件
        Specification<Users> specification = new Specification<Users>() {
            /**
                 Predicate:封装了单个的查询条件
                 Root<Users> root:查询对象的属性的封装
                 CriteriaQuery<?> query:封装了需要执行的查询中各个部分的信息,select from order by
                 CriteriaBuilder cb:查询条件的构造器,定义不同的查询条件
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // 定义查询条件:where name = 'coco'
                // cb.equal(arg0,arg1) 参数一:查询的属性。参数二:条件的值
                Predicate pre = cb.equal(root.get("name"), "coco");
                return pre;
            }
        };

        List<Users> list = this.usersJpaSpecificationExecutor.findAll(specification);
        for (Users user:list) {
            System.out.println(user);
        }
    }

    // JpaSpecificationExecutor   多条件查询,方式一
    @Test
    public void testJpaSpecificationExecutor2(){

        // Specification<Users>:用于封装查询条件
        Specification<Users> specification = new Specification<Users>() {
            /**
             Predicate:封装了单个的查询条件
             Root<Users> root:查询对象的属性的封装
             CriteriaQuery<?> query:封装了需要执行的查询中各个部分的信息,select from order by
             CriteriaBuilder cb:查询条件的构造器,定义不同的查询条件
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // 定义查询条件:where name = 'coco' and age = 20
                // cb.equal(arg0,arg1) 参数一:查询的属性。参数二:条件的值
                List<Predicate> list = new ArrayList<Predicate>();
                list.add(cb.equal(root.get("name"), "coco"));
                list.add(cb.equal(root.get("age"), "20"));
                // 定义Predicate[],将list转为Predicate[]后返回
                Predicate[] arr = new Predicate[list.size()];
                return cb.and( list.toArray(arr));
            }
        };

        List<Users> list = this.usersJpaSpecificationExecutor.findAll(specification);
        for (Users user:list) {
            System.out.println(user);
        }
    }

    // JpaSpecificationExecutor   多条件查询,方式二
    @Test
    public void testJpaSpecificationExecutor3(){

        // Specification<Users>:用于封装查询条件
        Specification<Users> specification = new Specification<Users>() {
            /**
             Predicate:封装了单个的查询条件
             Root<Users> root:查询对象的属性的封装
             CriteriaQuery<?> query:封装了需要执行的查询中各个部分的信息,select from order by
             CriteriaBuilder cb:查询条件的构造器,定义不同的查询条件
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // cb.equal(arg0,arg1) 参数一:查询的属性。参数二:条件的值
                // 定义查询条件:where name = 'coco' and age = 20 or id = 1
                return cb.or(cb.and(cb.equal(root.get("name"), "coco"), cb.equal(root.get("age"), "20")),
                             cb.equal(root.get("id"), "1"));   // 先与后或
                //return cb.and(cb.equal(root.get("name"), "coco"),cb.equal(root.get("age"), "20"));   // 与
                //return cb.or(cb.equal(root.get("name"), "coco"),cb.equal(root.get("age"), "20"));      // 或

            }
        };
        // 如果需要做降序排序
        Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC,"id"));
        // 根据条件查询
        List<Users> list = this.usersJpaSpecificationExecutor.findAll(specification,sort);
        for (Users user:list) {
            System.out.println(user);
        }
    }

}

测试一对多

package com.kevin.test;

import com.kevin.JpaApplication;
import com.kevin.dao.UsersJpaRepository;
import com.kevin.entity.Roles;
import com.kevin.entity.Users;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author kevin
 * @version 1.0
 * @description     测试一对多关联
 * @createDate 2019/3/21
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class OneToManyTest {

    @Autowired
    private UsersJpaRepository usersJpaRepository;

    // 一对多关联关系      添加功能
    @Test
    public void testSave(){
        // 创建一个用户
        Users users = new Users();
        users.setAddress("深圳");
        users.setAge(24);
        users.setName("老杨");
        // 创建一个角色
        Roles roles = new Roles();
        roles.setRolename("管理员");

        // 关联
        roles.getUsers().add(users);
        users.setRoles(roles);

        // 保存,sql语句会先操作roles角色表再操作users用户表
        this.usersJpaRepository.save(users);
    }

    // 一对多关联关系      查询功能
    @Test
    public void testFind(){

        // 根据id查出用户
        Users findById = this.usersJpaRepository.findById(7).get();
        System.out.println(findById);
        // 级联获取到用户的角色
        Roles roles = findById.getRoles();
        System.out.println(roles.getRolename());
    }





}

测试多对多

package com.kevin.test;

import com.kevin.JpaApplication;
import com.kevin.dao.RolesJpaRepository;
import com.kevin.entity.Menus;
import com.kevin.entity.Roles;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Set;

/**
 * @author kevin
 * @version 1.0
 * @description     测试多对多关联
 * @createDate 2019/3/21
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class ManyToManyTest {

    @Autowired
    private RolesJpaRepository rolesJpaRepository;

    // 多对多关联关系      添加功能
    @Test
    public void testSave(){

        // 创建角色对象
        Roles r = new Roles();
        r.setRolename("项目经理");

        // 创建菜单对象
        Menus menus = new Menus();
        menus.setMenusname("xxx管理系统");
        menus.setFatherid(0);

        Menus menus2 = new Menus();
        menus2.setMenusname("项目管理");
        menus2.setFatherid(1);

        // 关联
        r.getMenus().add(menus);
        r.getMenus().add(menus2);
        menus.getRoles().add(r);
        menus2.getRoles().add(r);
        // 保存
        this.rolesJpaRepository.save(r);

    }

    // 多对多关联关系      查询功能
    @Test
    public void testFind(){
        Roles roles = this.rolesJpaRepository.findById(2).get();
        System.out.println(roles.getRolename());
        Set<Menus> menus = roles.getMenus();
        for (Menus menus2:menus) {
            System.out.println(menus2);
        }
        
    }


}

猜你喜欢

转载自blog.csdn.net/qq1021979964/article/details/88760928
今日推荐