Spring Data JPA: Query by Example?

前端 未结 3 1932
渐次进展
渐次进展 2020-12-02 19:59

Using Spring Data JPA can I do a query by example where a particular entity instance is used as the search criteria?

For example (no pun intended), if I have a

3条回答
  •  囚心锁ツ
    2020-12-02 20:42

    Using Spring data's Specification interface I was able to approximate the use of query by example. Here's a PersonSpec class which implements Specification and requires an "example" person in order to setup the Predicate returned by the Specification:

    public class PersonSpec implements Specification {
    
      private final Person example;
    
      public PersonSpec(Person example) {
        this.example = example;
      }
    
      @Override
      public Predicate toPredicate(Root root, CriteriaQuery cq, CriteriaBuilder cb) {
        List predicates = new ArrayList<>();
    
        if (StringUtils.isNotBlank(example.getLastName())) {
          predicates.add(cb.like(cb.lower(root.get(Person_.lastName)), example.getLastName().toLowerCase() + "%"));
        }
    
        if (StringUtils.isNotBlank(example.getFirstName())) {
          predicates.add(cb.like(cb.lower(root.get(Person_.firstName)), example.getFirstName().toLowerCase() + "%"));
        }
    
        if (example.getEmployed() != null) {
          predicates.add(cb.equal(root.get(Person_.employed), example.getEmployed()));
        }
    
        if (example.getDob() != null) {
          predicates.add(cb.equal(root.get(Person_.dob), example.getDob()));
        }
    
        return andTogether(predicates, cb);
      }
    
      private Predicate andTogether(List predicates, CriteriaBuilder cb) {
        return cb.and(predicates.toArray(new Predicate[0]));
      }
    }
    

    The repository is simply:

    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    
    public interface PersonRepository extends JpaRepository, JpaSpecificationExecutor {}
    

    Usage example:

    Person example = new Person();
    example.setLastName("James");
    example.setEmployed(true);
    PersonSpec personSpec = new PersonSpec(example);
    List persons = personRepository.findAll(personSpec);
    

提交回复
热议问题