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