Spring Boot - Spring Boot integrates JPA (implements core interfaces and one-to-many, many-to-many)

Keywords: Spring Java Junit SQL

SpringBook integrates JPA

Spring Data:

Spring Data is Spring's framework for manipulating data. Spring Data Jpa is only a module based on JPA standard operation data under Spring Data framework.

Spring Data JPA:

Data is manipulated based on JPA standards. Simplify the code that operates on the persistence layer. All you need to do is write the interface.

The core interface provided by Spring Data JPA:

1.Repository interface
Provide method name queries
Provide queries and updates based on @Query annotations
2.CrudRepository interface
Inheriting Repository Interface and Implementing CRUD-related Operations
3.PagingAndSortingRepository interface
Inheriting CrudRepository Interface and Implementing Paging and Sorting Related Operations
4.JpaRepository interface
Inheriting PagingAndSortingRepository Interface to Implement JPA Specification Related Operations
5. JPA Specification Executor Interface
It does not belong to Repository system, exists alone, provides multi-condition support, and can add paging and sorting to queries

Write a case directly to test these five interfaces

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 Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- thymeleaf Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- springboot integration jpa Required dependency packages-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- mysql drive -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- druid Connection pool -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>

        <!-- Starter of Test Tool -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>


    </dependencies>

</project>

application.yml

spring:
  #Configuring data sources
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_crud?characterEncoding=utf-8
    username: root
    password: 123456
    #Using druid connection pool
    type: com.alibaba.druid.pool.DruidDataSource
  jpa:
    hibernate:
      #In forward engineering, if there are no tables in the data, a table will be created to update the data. If there are tables, the data will be updated directly.
      ddl-auto: update
    #Print and execute sql statements
    show-sql: true

Startup class

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 Integrate JPA
 *      Spring Data: Spring Data Spring provides a framework for manipulating data. Spring Data Jpa is only a module based on JPA standard operation data under Spring Data framework.
 *      Spring Data JPA: Data is manipulated based on JPA standards. Simplify the code that operates on the persistence layer. All you need to do is write the interface.
 *
 *   Spring Data JPA The core interface provided is:
 *      1.Repository Interface
 *          Provide method name naming queries
 *          Provide queries and updates based on @Query annotations
 *      2.CrudRepository Interface
 *          Inheriting Repository Interface and Implementing CRUD-related Operations
 *      3.PagingAndSortingRepository Interface
 *          Inheriting CrudRepository Interface and Implementing Paging and Sorting Related Operations
 *      4.JpaRepository Interface
 *          Inheriting PagingAndSortingRepository Interface and Implementing JPA Specification Related Operations
 *      5.JPASpecificationExecutor Interface
 *          It does not belong to Repository system, exists alone, provides multi-condition support, and can add paging and sorting to queries.
 *
 * @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 user entity class

package com.kevin.entity;

import javax.persistence.*;

/**
 * @author kevin
 * @version 1.0
 * @description     User Entity Class
 * @createDate 2019/3/20
 */
@Entity     // Represents this class as an entity class
@Table(name="t_users")      // Table names in corresponding databases
public class Users {

    @Id     // Representation as primary key
    @GeneratedValue(strategy = GenerationType.IDENTITY)     // Policies for this primary key
    @Column(name = "id")        // Column names
    private Integer id;
    @Column(name = "name")      // Column names
    private String name;
    @Column(name = "age")       // Column names
    private Integer age;
    @Column(name = "address")   // Column names
    private String address;

    @ManyToOne(cascade = CascadeType.PERSIST)      // ManyToOne represents many-to-one, and the cascade = CascadeType.PERSIST attribute is a cascade operation
    @JoinColumn(name = "roles_id")   // Maintaining foreign keys
    private Roles roles;        // Corresponding 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 role entity class

package com.kevin.entity;

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

/**
 * @author kevin
 * @version 1.0
 * @description     Role entity class
 *      One to many
 *      One role corresponds to multiple users
 * @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")  // One to many
    private Set<Users> users = new HashSet<>();     // Multiple users

    // cascade = CascadeType.PERSIST: Open cascade operations. fetch = FetchType.EAGER: Set to load immediately.
    @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)         // Many to many
    // @ JoinTable: Mapping intermediate table information, name: table name of intermediate table, join Columns: foreign key in intermediate table associated with primary key in current table
    @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 menu entity class

package com.kevin.entity;

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

/**
 * @author kevin
 * @version 1.0
 * @description     Menu table
 *      Many to many
 *      Multiple menus correspond to multiple roles
 * @createDate 2019/3/21
 */
@Entity
@Table(name = "t_menus")
public class Menus {

    @Id     // Represents the primary key.
    @GeneratedValue(strategy = GenerationType.IDENTITY)     // Primary key rules
    @Column(name = "menusid")   // Column names
    private Integer menusid;

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

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

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

    @ManyToMany(mappedBy = "menus")     // Many-to-many, mappedBy: The name of the associated field in 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 interface method named query

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 Use of interface: use of method name naming queries
 * @createDate 2019/3/20
 */
public interface UsersRepositoryByName extends Repository<Users,Integer> {

    // Method naming rules: Hump naming rules must be followed. FindBy (Keyword) +Property Name (Capitalization of the First Letter) +Query Conditions (Capitalization of the First Letter)
    // Search by name
    List<Users> findByName(String name);

    // Query by name and age
    List<Users> findByNameAndAge(String name,Integer age);

    // Use wildcards to query by name
    List<Users> findByNameLike(String name);
}

1.Repository interface @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 Use of the interface: @Query
 *
 * @createDate 2019/3/20
 */
@Transactional
public interface UsersRepositoryQueryAnnotation extends Repository<Users, Integer> {

    // @Query query
    // @ Query queries with object HQL statements. Query by name as a condition
    @Query("from Users where name = :name")
    List<Users> queryByNameUseHQL(@Param("name") String name);

    // @ Query queries with object SQL statements. Query by name, using standard SQL
    @Query(value="select * from t_users where name = ? ",nativeQuery = true)
    List<Users> queryByNameUseSQL(String name);

    // @Query update
    // @ Query updates name based on id
    @Query("update Users set name = :name where id = :id")
    @Modifying
    void updateUsersNameById(@Param("name")String name, @Param("id") Integer id);


}

2. Use of CrudRepository Interface

package com.kevin.dao;

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

/**
 * @author kevin
 * @version 1.0
 * @description     CrudRepository Interface use: mainly to complete some additions, deletions and modifications check operation.
 *      CrudRepository Interface inherits Repository interface
 * @createDate 2019/3/20
 */
public interface UsersCrudRepository extends CrudRepository<Users,Integer> {

}

3. Use of PagingAndSortRepository Interface

package com.kevin.dao;

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

/**
 * @author kevin
 * @version 1.0
 * @description     PagingAndSortingRepository Use. Mainly sorting, paging, etc.
 * @createDate 2019/3/20
 */
public interface UsersPagingAndSortingRepository extends PagingAndSortingRepository<Users,Integer> {

}

4. The Use of JPARepository Interface in Users

package com.kevin.dao;

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

/**
 * @author kevin
 * @version 1.0
 * @description         JpaRepository The use of the interface adapts the return value of the method in the inherited parent interface.
 *      Parametric 1 T: Entity classes that currently need to be mapped
 *      Parametric 2 ID: Type of OID in the entity class currently mapped
 * @createDate 2019/3/20
 */
public interface UsersJpaRepository extends JpaRepository<Users,Integer> {

}

4. The Use of JPARepository Interface in Roles

package com.kevin.dao;

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

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

}

5. Use of Jpa Specification Executor Interface

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 Use to provide multi-conditional support and to add paging and sorting to queries
 * @createDate 2019/3/21
 */
public interface UsersJpaSpecificationExecutor extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users> {
}

The following test methods use Test in SpringBoot

 

Test method name queries and @Query in Repository

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     Test Repository function, method name and @Quert function
 * @createDate 2019/3/20
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersRepositoryTest {

    @Autowired
    private UsersRepositoryByName usersRepositoryByName;

    @Autowired
    private UsersRepositoryQueryAnnotation usersRepositoryQueryAnnotation;

    // Repository -- Method Naming Test, querying by name as a condition
    @Test
    public void testFindByName(){

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

    // Repository -- Method Naming Test, queried by name and age as conditions
    @Test
    public void testFindByNameAndAge(){

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

    // Repository -- Method Name Naming Test, Wildcard Query Based on Name
    @Test
    public void testFindByNameLike(){

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

    // Repository - @Quert test, query HQL by name
    @Test
    public void testQueryByNameUseHQL(){

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

    // Repository - @Quert test, query SQL by name
    @Test
    public void testQueryByNameUseSQL(){

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

    // Repository - @Quert test, update name according to id
    @Test
    @Transactional      //@ Transactional rolls back automatically when used with @Test
    @Rollback(false)        // Cancel automatic rollback
    public void testUpdateUsersNameById(){

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

    }


}

Testing CrudRepository Interface

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        Testing CrudRepository, adding, deleting and modifying check function
 * @createDate 2019/3/20
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersCrudRepositoryTest {

    @Autowired
    private UsersCrudRepository usersCrudRepository;


    // CrudRepository Testing, New Functions
    @Test
    public void testCrudRepositorySave(){
        Users user = new Users();
        user.setAddress("Shanghai");
        user.setAge(22);
        user.setName("java");
        this.usersCrudRepository.save(user);
    }

    // CrudRepository test, update function, save method is insert and update
    @Test
    public void testCrudRepositoryUpdate(){
        Users user = new Users();
        user.setAddress("Shanghai");
        user.setAge(22);
        user.setName("scala");
        user.setId(4);
        this.usersCrudRepository.save(user);
    }

    // CrudRepository test, query function, query according to id
    @Test
    public void testCrudRepositoryFindById(){
        Users user = this.usersCrudRepository.findById(1).get();
        System.out.println(user.toString());
    }

    // CrudRepository test, query function, query all
    @Test
    public void testCrudRepositoryFindAll(){

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

    // CrudRepository test, delete function, delete according to id
    @Test
    public void testCrudRepositoryDeleteById(){

        this.usersCrudRepository.deleteById(5);
    }

}

Test the PagingAndSortingRepository interface

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     Testing PagingAndSort Repository Sorting and Paging Functions
 * @createDate 2019/3/20
 */

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

    @Autowired
    private UsersPagingAndSortingRepository usersRepositoryPagingAndSorting;


    // PagingAndSorting Repository Sorting Function
    @Test
    public void testPagingAndSortingRepositorySort(){
        // Order defines sorting rules. Descending order
        Order order = new Order(Direction.DESC,"id");
        //Sort objects encapsulate sorting rules
        Sort sort = new Sort(order);
        List<Users> list = (List<Users>)this.usersRepositoryPagingAndSorting.findAll(sort);
        for (Users user:list) {
            System.out.println(user.toString());
        }
    }

    // PagingAndSorting Repository Paging Function
    @Test
    public void testPagingAndSortingRepositoryPaging(){
        // Pageable: Encapsulates the paging parameters, the current page, and the number of items displayed per page. Note: Its current page starts at 0
        // PageRequest (page,size) page: The current page. Size: Number of items displayed per page
        Pageable pageable = new PageRequest(0,2);

        Page<Users> list = this.usersRepositoryPagingAndSorting.findAll(pageable);
        System.out.println("Total number:"+list.getTotalElements());
        System.out.println("Total pages:"+list.getTotalPages());

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

    // PagingAndSorting Repository Sorting + Paging Function
    @Test
    public void testPagingAndSortingRepositorySortAndPaging(){

        // Sort ascending according to id
        Sort sort = new Sort(new Order(Direction.ASC,"id"));
        // Start by displaying two pieces of data based on 0 and sort them
        Pageable pageable = new PageRequest(0,2,sort);

        Page<Users> list = this.usersRepositoryPagingAndSorting.findAll(pageable);
        System.out.println("Total number:"+list.getTotalElements());
        System.out.println("Total pages:"+list.getTotalPages());

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



}

Testing JPARepository interface

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         Testing JpaRepository, with the most specific functions
 * @createDate 2019/3/21
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersJpaRepositoryTest {

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

    // JpaRepository adds or updates functionality, and the save method determines that if the database does not have this data, it inserts and updates if it exists.
    @Test
    public void testSave(){
        Users users = new Users();
        users.setAddress("Guangzhou");
        users.setAge(22);
        users.setName("cnq");
        this.usersJpaRepository.save(users);
    }

    // JpaRepository query function, query according to id
    @Test
    public void testFindById(){
        Users user = this.usersJpaRepository.findById(1).get();
        System.out.println(user);
    }

    // JpaRepository query function, query all
    @Test
    public void testFindAll(){
        List<Users> list = this.usersJpaRepository.findAll();
        for (Users user:list) {
            System.out.println(user);
        }
    }

    // JpaRepository deletion function, query by id
    @Test
    public void testDeleteById(){
        this.usersJpaRepository.deleteById(6);
    }

    // JpaRepository Delete Function, Delete by Object
    @Test
    public void testDelete(){
        Users users = new Users();
        users.setAddress("Guangzhou");
        users.setAge(22);
        users.setName("cnq");
        users.setId(6);
        this.usersJpaRepository.delete(users);
    }




}

Test the JpaSpecification Excutor interface

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     Testing Jpa Specification Executor function, multi-condition query
 * @createDate 2019/3/21
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class UsersJpaSpecificationExecutorTest {

    @Autowired
    private UsersJpaSpecificationExecutor usersJpaSpecificationExecutor;

    // Jpa Specification Executor Single Conditional Query
    @Test
    public void testJpaSpecificationExecutor1(){

        // Specification < Users >: Used to encapsulate query conditions
        Specification<Users> specification = new Specification<Users>() {
            /**
                 Predicate: Encapsulating a single query condition
                 Root<Users> root: Encapsulation of attributes of query objects
                 CriteriaQuery<?> query: Encapsulate the information of each part of the query that needs to be executed, select from order by
                 CriteriaBuilder cb: Constructor of query conditions, defining different query conditions
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // Define the query condition: where name = coco'
                // cb.equal(arg0,arg1) parameter 1: the attributes of the query. PARAMETER 2: THE VALUE OF CONDITIONS
                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);
        }
    }

    // Jpa Specification Executor multi-condition query, mode 1
    @Test
    public void testJpaSpecificationExecutor2(){

        // Specification < Users >: Used to encapsulate query conditions
        Specification<Users> specification = new Specification<Users>() {
            /**
             Predicate: Encapsulating a single query condition
             Root<Users> root: Encapsulation of attributes of query objects
             CriteriaQuery<?> query: Encapsulate the information of each part of the query that needs to be executed, select from order by
             CriteriaBuilder cb: Constructor of query conditions, defining different query conditions
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // Define the query condition: where name ='coco'and age = 20
                // cb.equal(arg0,arg1) parameter 1: the attributes of the query. PARAMETER 2: THE VALUE OF CONDITIONS
                List<Predicate> list = new ArrayList<Predicate>();
                list.add(cb.equal(root.get("name"), "coco"));
                list.add(cb.equal(root.get("age"), "20"));
                // Define Predicate [], convert list to Predicate [] and return
                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);
        }
    }

    // Jpa Specification Executor multi-condition query, mode 2
    @Test
    public void testJpaSpecificationExecutor3(){

        // Specification < Users >: Used to encapsulate query conditions
        Specification<Users> specification = new Specification<Users>() {
            /**
             Predicate: Encapsulating a single query condition
             Root<Users> root: Encapsulation of attributes of query objects
             CriteriaQuery<?> query: Encapsulate the information of each part of the query that needs to be executed, select from order by
             CriteriaBuilder cb: Constructor of query conditions, defining different query conditions
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                // cb.equal(arg0,arg1) parameter 1: the attributes of the query. PARAMETER 2: THE VALUE OF CONDITIONS
                // Define the query condition: 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"));   // First or later or
                //Return cb. and (cb. equal (root. get ("name"), coco), cb. equal (root. get ("age"), 20); //and
                //Return cb.or (cb.equal (root.get ("name"), coco), cb.equal (root.get ("age"), 20); //or

            }
        };
        // If you need to do descending sort
        Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC,"id"));
        // Query according to conditions
        List<Users> list = this.usersJpaSpecificationExecutor.findAll(specification,sort);
        for (Users user:list) {
            System.out.println(user);
        }
    }

}

Test one-to-many

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     Testing one-to-many associations
 * @createDate 2019/3/21
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class OneToManyTest {

    @Autowired
    private UsersJpaRepository usersJpaRepository;

    // One-to-many Association adding function
    @Test
    public void testSave(){
        // Create a user
        Users users = new Users();
        users.setAddress("Shenzhen");
        users.setAge(24);
        users.setName("Lao Yang");
        // Create a role
        Roles roles = new Roles();
        roles.setRolename("Administrators");

        // Relation
        roles.getUsers().add(users);
        users.setRoles(roles);

        // Save. The sql statement will first operate the roles role table and then the users user table.
        this.usersJpaRepository.save(users);
    }

    // One-to-many Association Query Function
    @Test
    public void testFind(){

        // Identify users based on id
        Users findById = this.usersJpaRepository.findById(7).get();
        System.out.println(findById);
        // Cascaded access to user roles
        Roles roles = findById.getRoles();
        System.out.println(roles.getRolename());
    }





}

Test many-to-many

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     Testing many-to-many associations
 * @createDate 2019/3/21
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = JpaApplication.class)
public class ManyToManyTest {

    @Autowired
    private RolesJpaRepository rolesJpaRepository;

    // Multi-to-Multi Relational Addition Function
    @Test
    public void testSave(){

        // Create role objects
        Roles r = new Roles();
        r.setRolename("project manager");

        // Create menu objects
        Menus menus = new Menus();
        menus.setMenusname("xxx management system");
        menus.setFatherid(0);

        Menus menus2 = new Menus();
        menus2.setMenusname("project management");
        menus2.setFatherid(1);

        // Relation
        r.getMenus().add(menus);
        r.getMenus().add(menus2);
        menus.getRoles().add(r);
        menus2.getRoles().add(r);
        // Preservation
        this.rolesJpaRepository.save(r);

    }

    // Multi-to-Multi Association Query Function
    @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);
        }
        
    }


}

 

Posted by Fireglo on Mon, 25 Mar 2019 20:33:29 -0700