首页 > 其他分享 >Spring Data JPA : 查-条件化查询Specification

Spring Data JPA : 查-条件化查询Specification

时间:2023-10-23 15:15:50浏览次数:40  
标签:JPA Spring Specification private javax person import response persistence

条件化查询  用查询条件创建Specification对象 参考Spring Data JPA Specification查询

使用Criteria查询 Criteria查询是面向对象查询, root就是一个对象,root.get("name")就是name属性可以级联获取属性

每一个查询条件创建一个Specification对象,如果有多个查询条件,就把多个Specification对象and或or成最后一个总的Specification对象。

有实体类Person如下

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Data;

@Data
@Entity
@Table(name = "tb_person_info")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column
    private String firstName;
    @Column
    private String lastName;
    @Column
    private Integer age;
    @Column
    private String phone;
    @Column
    private String address;
}
View Code

它的form-PersonRequest如下, age 接收一个数组

import java.util.List;

import lombok.Data;

@Data
public class PersonRequest {

    private Long id;
    private String firstName;
    private String lastName;
    private List<Integer> age;
    private String phone;
    private String address;
}
View Code

它的form-PersonResponse如下

import lombok.Data;

@Data
public class PersonResponse {

    private Long id;
    private String firstName;
    private String lastName;
    private Integer age;
    private String phone;
    private String address;
}
View Code

Repository层如下

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


@Repository
public interface PersonRepository extends JpaRepository<Person, Long>, JpaSpecificationExecutor<Person> {

}
View Code

如果对它进行组合条件查询,如果查询条件互相都是and关系,那么很好做。如果查询条件有and 和 or 的关系会相对复杂一些

所有查询条件都是and关系, age 是in 查询

 

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

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonRepository personRepository;
    
    @Override
    public List<PersonResponse> findListAllAnd2(PersonRequest request) {

        Specification<Person> specification = new Specification<Person>() {
            @Override
            public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
              
                //1.调用criteriaBuilder.conjunction()方法 返回一个默认true 的 and predicate 
                List<Predicate> predicates = new ArrayList<>();
                               
                //把所有查询条件add到这个predicate的expression
                if (StringUtils.hasText(request.getFirstName())) {
                    predicates.add(criteriaBuilder.like(root.get("firstName"), "%" + request.getFirstName() + "%"));
                }
                if (StringUtils.hasText(request.getLastName())) {
                    predicates.add(criteriaBuilder.like(root.get("lastName"), "%" + request.getLastName() + "%"));
                }
                if (request.getAge() != null && request.getAge().size() > 0) {
                    In<Object> in = criteriaBuilder.in(root.get("age"));
                    for (Integer age : request.getAge()) {
                        in.value(age);
                    }
                    predicates.add(criteriaBuilder.and(in));
                }
                //返回predicate
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };

        List<Person> persons = personRepository.findAll(specification);
        List<PersonResponse> responses = new ArrayList<PersonResponse>();
        for (Person person : persons) {
            PersonResponse response = new PersonResponse();
            modelToResponse(person, response);
            responses.add(response);
        }
        return responses;
    }
    
    private void modelToResponse(Person person, PersonResponse response) {
        response.setId(person.getId());
        response.setFirstName(person.getFirstName());
        response.setLastName(person.getLastName());
        response.setAddress(person.getAddress());
        response.setAge(person.getAge());
        response.setPhone(person.getPhone());
    }
}
View Code

 

查询条件存在and 和 or 的关系,比如 (A or B )and C

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

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


@Service
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonRepository personRepository;

    @Override
    public List<PersonResponse> findListAndOr(PersonRequest request) {

        Specification<Person> specification = new Specification<Person>() {
            @Override
            public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {

                // A conjunction with zero conjuncts is true.
                Predicate predicate = criteriaBuilder.conjunction();

                // or 条件
                List<Predicate> orPredicates = new ArrayList<Predicate>();
                if (StringUtils.hasText(request.getFirstName())) {
                    orPredicates.add(criteriaBuilder.like(root.get("firstName"), "%" + request.getFirstName() + "%"));
                }
                if (StringUtils.hasText(request.getLastName())) {
                    orPredicates.add(criteriaBuilder.like(root.get("lastName"), "%" + request.getLastName() + "%"));
                }
                if (orPredicates.size() > 0) {
                    predicate.getExpressions().add(criteriaBuilder.or(orPredicates.toArray(new Predicate[orPredicates.size()])));
                }

                // and 条件
                if (null != request.getPhone()) {
                    predicate.getExpressions().add(criteriaBuilder.equal(root.get("phone"), request.getPhone()));
                }
                return predicate;
            }
        };

        List<Person> persons = personRepository.findAll(specification);
        List<PersonResponse> responses = new ArrayList<PersonResponse>();
        for (Person person : persons) {
            PersonResponse response = new PersonResponse();
            modelToResponse(person, response);
            responses.add(response);
        }
        return responses;
    }

    private void modelToResponse(Person person, PersonResponse response) {
        response.setId(person.getId());
        response.setFirstName(person.getFirstName());
        response.setLastName(person.getLastName());
        response.setAddress(person.getAddress());
        response.setAge(person.getAge());
        response.setPhone(person.getPhone());
    }
}
View Code

它生成的sql如下  where (person0_.first_name like ? or person0_.last_name like ?) and person0_.phone= 12 实现了 ( A or B) and C

Hibernate: select person0_.id as id1_7_, person0_.address as address2_7_, person0_.age as age3_7_, person0_.first_name as first_name4_7_, person0_.last_name as last_name5_7_, person0_.phone as phone6_7_ from tb_person_info person0_ where (person0_.first_name like ? or person0_.last_name like ?) and person0_.phone=12

 

标签:JPA,Spring,Specification,private,javax,person,import,response,persistence
From: https://www.cnblogs.com/dreamstar99/p/17782354.html

相关文章

  • 使用JpaRepository的save方法执行成功,数据库却没有保存
    使用JpaRepository的save方法执行成功,数据库却没有保存可能是和事务有关的,这里用JpaRepository的flush方法,就可以了@TestvoidtestUserRespositorySave(){Useruser=newUser("小明","123456",18);userRespository.save(user);userRespository.flush();}原......
  • JPA查询修改数据,但是未保存到数据库,数据库却修改了,因为对查询出的Entity实体对象,修改s
    JPA查询修改数据,但是未保存到数据库,数据库却修改了,因为对查询出的Entity实体对象,修改set了属性。导致事务提交时候修改了数据库的数据使用JPA查询数据,对查询出来的结果进行修改,但是不保存数据库,最终数据库却做了同样的修改。JPA对象的四种状态瞬时状态:瞬时状态的实体就是一......
  • Springboot定时任务处理
    详细讲解SpringBoot利用注解创建静态定时任务,利用接口创建动态定时任务,利用@EnableAsync和@Async创建多线程定时任务阅读目录:序言一、静态:基于注解二、动态:基于接口三、多线程定时任务 阅读正文:回到顶部序言使用SpringBoot创建定时任务非常简单,目前主要有以下三......
  • Spring Cloud OpenFeign系列:简介和使用
    目录一、简介二、使用1、创建父工程2、创建order-service模块3、创建order-client模块三、效果四、配置说明1、超时配置全局超时配置局部超时配置2、Gzip压缩设置3、所有配置五、负载均衡五、对比Feign一、简介官网:https://spring.io/projects/spring-cloud-openfeign文档:https......
  • springboot整合swagger3.0
    pom文件中导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency>application.yml中写入配置swagger:enable:tr......
  • springboot+vue学习(2)
    1、ref :为子组件指定一个索引ID,给元素或者组件注册引用信息。refs是一个对象,包含所有的ref组件。<divid="parent"><user-profileref="profile"></user-profile>(子组件)</div>varparent=newVue({el:'#parent'})//访问子组件varchild=parent.$ref......
  • Error creating bean with name 'org.springframework.web.servlet.handler.BeanNameU
    Errorcreatingbeanwithname'org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping':Instantiationofbeanfailed;nestedexceptionisorg.springframework.beans.BeanInstantiationException:Failedtoinstantiate[org.springframework......
  • springboot+vue学习
    最近遇到一个问题,在一个页面需要动态渲染页面内的表单,其中包括checkbox表单类型,并且使用Element组件UI时,此时v-model绑定的数据也是动态生成的例如:定义的data的form里面是空对象,需要动态生成里面的keyexportdefault{data(){return{form:{}......
  • Springboot基础
    接口测试工具:postman参数原始方法Springboot方式复杂实体参数数组实体参数日期参数JSON参数路径参数响应数据......
  • Redis和Spring Boot:如何协作提高您的应用程序性能
    环境说明:Windows10+Idea2021.3.2+Jdk1.8+SpringBoot2.3.1.RELEASE前言Redis是一种高效的非关系型数据库,能够支持复杂的数据结构和操作。在SpringBoot应用中,集成Redis可以提供更好的性能和扩展性。本文将介绍如何在SpringBoot应用中集成Redis并使用其基本功能......