El uso y explicación detallada de Spring Data jpa: consulta dinámica compleja y paginación, clasificación

1. Utilice la especificación para implementar consultas complejas

(1) ¿Qué es la especificación?

La especificación es una interfaz en springDateJpa. Es una extensión para algunas operaciones CRUD básicas de jpa. Puede entenderse como una interfaz de consulta compleja de Spring jpa. En segundo lugar, debemos comprender la consulta Criteria, que es una consulta de tipo seguro y más orientada a objetos. Y Spring Data JPA admite la consulta de criterios JPA2.0, y la interfaz correspondiente es JpaSpecificationExecutor.

La interfaz JpaSpecificationExecutor se define básicamente alrededor de la interfaz de Especificación. Solo el siguiente método se define en la interfaz de Especificación:

Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); 

Conceptos básicos de la consulta Criterios:

La consulta de criterios se basa en el concepto de metamodelo. El metamodelo se define para entidades gestionadas de unidades de persistencia específicas. Estas entidades pueden ser clases de entidad, clases integradas o clases parentales mapeadas.

Interfaz CriteriaQuery:

Representa un objeto de consulta de nivel superior específico, que contiene varias partes de la consulta, como: seleccionar, desde, dónde, agrupar por, ordenar por, etc. Nota: El objeto CriteriaQuery solo funciona para consultas de criterios de tipo entidad o incrustado.

Raíz:

Representa el objeto raíz de la consulta Criteria. La raíz de la consulta Criteria define el tipo de entidad y puede obtener los resultados deseados para la navegación futura. Es similar a la cláusula FROM de la consulta SQL.
La instancia raíz se escribe y define los tipos que pueden aparecer en la cláusula FROM de la consulta. La raíz representa la clase de entidad que se consultará, la consulta puede obtener el objeto raíz de ella, decirle a jpa qué clase de entidad consultar y también puede agregar condiciones de consulta, y también puede combinar el objeto EntityManager para obtener el objeto TypedQuery de consulta final.

Interfaz CriteriaBuilder:

Predicado, un objeto constructor utilizado para construir CritiaQuery: un tipo de predicado simple o complejo es en realidad equivalente a una condición o una combinación de condiciones. Se puede obtener a través de EntityManager.getCriteriaBuilder.

Dos, use la Especificación para consultas dinámicas complejas

La dependencia de maven puede seguir usando el capítulo anterior, aquí para modificar la clase de entidad y la capa del controlador.
Solicitar clase de entidad:

@Data
public class AccountRequest {
    
    

    //从第几页开始
    private Integer page;

    //每一页查询多少
    private Integer limit;

    private String id;

    private String name;

    private String pwd;

    private String email;

    private Integer[] types;

}

Clase de entidad:

@Data
@Entity
@Table(name = "account")
@ToString
@EntityListeners(AuditingEntityListener.class)
public class Account {
    
    

    @Id
    @GenericGenerator(name = "idGenerator", strategy = "uuid")
    @GeneratedValue(generator = "idGenerator")
    private String id;

    @Column(name = "username", unique = true, nullable = false, length = 64)
    private String username;

    @Column(name = "password", nullable = false, length = 64)
    private String password;

    @Column(name = "email", length = 64)
    private String email;

    @Column(name = "type")
    private Short type;

    @CreatedDate
    @Column(name = "create_time", nullable = false)
    private LocalDateTime createTime;

}

Capa de repositorio:

public interface AccountRepository extends JpaRepository<Account,String>, JpaSpecificationExecutor<Account> {
    
    }

Capa de controlador (o directamente omitir la capa de servicio)

@Autowired
    private AccountRepository repository;


    @PostMapping("/get")
    public List<Account> get(@RequestBody AccountRequest request){
    
    
        Specification<Account> specification = new Specification<Account>() {
    
    

            @Override
            public Predicate toPredicate(Root<Account> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) {
    
    
                //所有的断言 及条件
                List<Predicate> predicates = new ArrayList<>();
                //精确匹配id pwd
                if (request.getId() != null) {
    
    
                    predicates.add(builder.equal(root.get("id"), request.getId()));
                }
                if (request.getPwd() != null) {
    
    
                    predicates.add(builder.equal(root.get("password"), request.getPwd()));
                }
                //模糊搜索 name
                if (request.getName() != null && !request.getName().equals("")) {
    
    
                    predicates.add(builder.like(root.get("username"), "%" + request.getName() + "%"));
                }
                if (request.getEmail() != null && !request.getEmail().equals("")) {
    
    
                    predicates.add(builder.like(root.get("email"), "%" + request.getEmail() + "%"));
                }
                //in范围查询
                if (request.getTypes() != null) {
    
    
                    CriteriaBuilder.In<Object> types = builder.in(root.get("type"));
                    for (Integer type : request.getTypes()) {
    
    
                        types = types.value(type);
                    }
                    predicates.add(types);
                }
                return builder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        List<Account> accounts = repository.findAll(specification);

        return accounts;
    }

Al reescribir el método toPredicate de Especificación, se completa una consulta SQL dinámica tan compleja y se puede llamar directamente mediante una solicitud posterior.

Tres, paginación y clasificación

@PostMapping("/page")
    public List<Account> getPage(@RequestBody AccountRequest request){
    
    

        Specification<Account> specification = new Specification<Account>() {
    
    
            @Override
            public Predicate toPredicate(Root<Account> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
    
    
                List<Predicate> predicates = new ArrayList<>();
                //do anything
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        //表示通过createTime进行 ASC排序
        PageRequest page = new PageRequest(request.getPage() - 1, request.getLimit(), Sort.Direction.ASC, "createTime");
        Page<Account> pageInfo = repository.findAll(specification, page);

        return pageInfo.getContent();
    }

El código anterior es para construir reglas de paginación y clasificación a través de PageRequest después de una consulta compleja, paginación y clasificación. Pase la página de inicio y el número de cada página, así como las reglas de clasificación y el atributo por el que se debe ordenar. Jpa comienza desde la página 0, por lo que debe prestar atención al transferir parámetros.
Por supuesto, si no necesita realizar consultas complejas, también puede realizar consultas de paginación y clasificación de los datos.
Modifique el repositorio para heredar PagingAndSortingRepository.

@Repository
public interface AccountRepository extends JpaRepository<Account,String>, JpaSpecificationExecutor<Account> , PagingAndSortingRepository<Account,String> {
    
    
    Page<Account> findByAge(int age, Pageable pageable);
}

Cuando lo use, cree primero el parámetro paginable y luego páselo.

//显示第1页每页显示3条
PageRequest pr = new PageRequest(1,3);
//根据年龄进行查询
Page<Account> stus = accountPageRepository.findByAge(22,pr); 

La clasificación también es la misma, crea un método en el repositorio

List<Account> findByPwd(String pwd, Sort sort);

Pase el objeto de clasificación al llamar

//设置排序方式为username降序
List<Account> accs = accountPageRepository.findByAge("123456",new Sort(Sort.Direction.DESC,"username"));
//设置排序以username和type进行升序
acc = accountPageRepository.findByAge("123456",new Sort(Sort.Direction.ASC,"username","type"));
//设置排序方式以name升序,以address降序
Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC,"name"),new Sort.Order(Sort.Direction.DESC,"type"));
accs = accountPageRepository.findByAge("123456",sort);

Conclusión:
Este pequeño contenido casi ha terminado. Si necesita más materiales de aprendizaje y tutoriales sobre Java, puede hacer clic para ingresar, el código es: csbb , gratis, intercambiemos y aprendamos juntos.

Preguntas de la entrevista en todos los aspectos de Java

Inserte la descripción de la imagen aquí

Todos los aspectos de los materiales de aprendizaje de Java, considerando la extensión del problema, solo pueden mostrar una pequeña parte

Inserte la descripción de la imagen aquí

Tutoriales de aprendizaje de Java, siempre que sea un punto de habilidad requerido para el desarrollo y la arquitectura de back-end, ¡hay tutoriales aquí!

Inserte la descripción de la imagen aquí
Finalmente, ¡les deseo todo el éxito en su trabajo, con un salario anual de millones! ! !

Supongo que te gusta

Origin blog.csdn.net/m0_45270667/article/details/109384393
Recomendado
Clasificación