The use of jpaspecification executor interface of SpringDataJPA

The use of jpaspecification executor interface of SpringDataJPA

Jpaspecification executor: this interface cannot be used alone. As shown in the figure above, this interface does not directly or indirectly inherit the Repository, so this interface is not the implementation interface of the Repository, and there is no corresponding method to operate the database. It must be used in combination with the above three interfaces, mainly non primary key query and some other queries.
The jpasecification executor interface is a tool interface independent of the previous several ports, so it can not be used alone. Next, the method is implemented in combination with the JpaRepository interface.
Because of the package import, POJO and applicationContext.xml are created, the database file is the same as the previous position file, so the code is no longer pasted, and its interface and test class are directly pasted.

  1. Create interface implementation inheritance
package com.OVA.dao;

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

import com.OVA.pojo.Users;

/**
 * @author OVA_Wom 
 * JpaSpecificationExecutor
 * This interface cannot be used alone. It needs to be used with other interfaces in JPA. It is used for queries with non primary key conditions, mainly dealing with multi condition queries and sorting paging
 * Reason: jpaspecification executor this interface does not inherit the JPA tag interface of repository, and Spring cannot generate the corresponding proxy object
 **/
public interface UserDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users> {
	
}
  1. Test class writing
package test;

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

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.OVA.dao.UserDao;
import com.OVA.pojo.Users;

/**
 * @author OVA_Wom JpaSpecificationExecuto Test interface
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestJpaSpecificationExecutorTest {
	@Autowired
	private UserDao userdao;
	Users users = null;

	// Single condition query, query data according to user name
	@Test
	public void TestFindByName() {
		/*
		 * Generics are query objects. Specification is actually a query object that encapsulates query rules
		 * Note: Specification is actually the encapsulation of hibernatejpa QBC query method,
		 * Among them, CriteriaBuilder,CriteriaQuery
		 * Root,Predicate Object; because Specification is an interface type
		 * So we use anonymous inner class to implement this interface, and let it call back to predict method
		 */
		Specification<Users> specification = new Specification<Users>() {
			/*
			 * Predicate Object encapsulates the condition to be queried. Root is the root object of the query. A secondary encapsulation is made for the object to be queried, which is convenient to go to all fields in the database
			 * CriteriaQuery<?>Encapsulates a basic query, select* from object name;
			 * CriteriaBuilder Create query, create criteriaquery <? > object
			 */
			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				// Compare names
				Predicate pre = cb.equal(root.get("username"), "Miss Tung");
				return pre;
			}
		};
		List<Users> findAll = userdao.findAll(specification);
		for (Users users : findAll) {
			System.out.println(users);
		}
	}

	// Mode 1 multiple plus query
	// User name and age as query criteria
	@Test
	public void TestFindByNameAndAge1() {
		Specification<Users> specification = new Specification<Users>() {

			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				// Set multiple query criteria
				List<Predicate> list = new ArrayList<>();
				Predicate username = cb.equal(root.get("username"), "Miss Tung");
				// Greater than or equal to 40
				Predicate userage = cb.greaterThanOrEqualTo(root.get("userage"), 40);
				list.add(username);
				list.add(userage);
				/*
				 * If there are more than one and two query conditions, we need to use the Predicate [] array method
				 * Create an array of predict [] with the length of list.size()
				 */
				Predicate[] predicates = new Predicate[list.size()];
				// list.toArray transfers the data in the collection to the array
				Predicate[] array = list.toArray(predicates);
				// This method needs to pass in an array
				Predicate and = cb.and(array);
				return and;
			}
		};
		List<Users> findAll = userdao.findAll(specification);
		for (Users users : findAll) {
			System.out.println(users);
		}
	}

	// Mode 2 multi criteria query
	// User name or age as query criteria
	@Test
	public void TestFindByNameAndAge2() {

		Specification<Users> specification = new Specification<Users>() {

			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//Users younger than 30 or whose name is Miss Dong
				return cb.or(cb.equal(root.get("username"), "Miss Tung"), cb.lessThanOrEqualTo(root.get("userage"), 30));
			}
		};
		List<Users> findAll = userdao.findAll(specification);
		for (Users users : findAll) {
			System.out.println(users);
		}
	}
	@Test
	//Implementation of sorting by jpaspecification executor
	//Query the names of users whose names begin with directors, and sort them in descending order of ID
	public void TestFindByNameSort(){
		Specification<Users> specification=new Specification<Users>() {

			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.like(root.get("username").as(String.class), "Dong%");
			}
			
		};
		//sort
		Sort sort=new Sort(Direction.DESC,"userid");
		 List<Users> findAll = userdao.findAll(specification,sort);
		for (Users users : findAll) {
			System.out.println(users);
		}
	}
	@Test
	//Implementation of paging by jpaspecification executor
	//Name of the user whose name starts with the director
	public void TestFindByNamePage(){
		Specification<Users> specification=new Specification<Users>() {

			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.like(root.get("username").as(String.class), "Dong%");
			}
			
		};
		//paging
		//Number of items displayed on one page
		int size=2;
		//Print page number the following table starts at 0
		int page=0;
		Pageable pageable=new PageRequest(page, size);
		 Page<Users> findAll = userdao.findAll(specification,pageable);
		 System.out.println("PageCount"+findAll.getTotalPages());
		 System.out.println("Total number of pages"+findAll.getTotalElements());
		for (Users users : findAll.getContent()) {
			System.out.println(users);
		}
	}
	@Test
	//Jpaspecification executor implements query paging and sorting
	//The names of users whose query names start with directors are in descending order of ID and displayed in pages
	//Because the sorting object is integrated into the pable object, we call PageRequest(page, size, sort)
	public void TestFindByNamePageAndSort(){
		Sort sort = new Sort(Direction.DESC,"userid");
		int size=2;
		int page=0;
		PageRequest pageRequest = new PageRequest(page, size, sort);
		Specification<Users> specification=new Specification<Users>() {

			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				// TODO Auto-generated method stub
				return cb.like(root.get("username"), "Dong%");
			}
		};
		Page<Users> findAll = userdao.findAll(specification,pageRequest);
		System.out.println("PageCount"+findAll.getTotalPages());
		System.out.println("Total number:"+findAll.getTotalElements());
		for (Users users : findAll.getContent()) {
		System.out.println(users);	
		}
	}
}


The code has been annotated in detail. The above is the basic content of the jpaspecification executo interface. Please correct the shortcomings.

Published 10 original articles, won praise and 924 visitors
Private letter follow

Tags: Database xml Java Junit

Posted on Wed, 05 Feb 2020 09:19:16 -0500 by exeterdad