Spring Data JPA:按示例查询?

使用Spring Data JPA可以通过示例进行查询,其中特定实体实例用作搜索条件吗?

例如(没有双关语),如果我有一个看起来像这样的Person实体:

 @Entity public class Person { private String firstName; private String lastName; private boolean employed; private LocalDate dob; ... } 

我可以找到所有在1977年1月1日出生的史密斯姓氏的雇员,举个例子:

 Person example = new Person(); example.setEmployed(true); example.setLastName("Smith"); example.setDob(LocalDate.of(1977, Month.JANUARY, 1)); List foundPersons = personRepository.findByExample(example); 

Spring数据依赖于JPA和EntityManager,而不是Hibernate和Session,因此您没有开箱即用的findByExample。 您可以使用spring数据自动查询创建,并使用以下签名在存储库中编写方法:

 List findByEmployedAndLastNameAndDob(boolean employed, String lastName, LocalDate dob); 

Spring Data现在可以实现这一点。 查看http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example

 Person person = new Person(); person.setLastname("Smith"); Example example = Example.of(person); List results = personRepository.findAll(example); 

请注意,这需要最新的2016版本

   org.springframework.data spring-data-jpa 1.10.1.RELEASE   org.springframework.data spring-data-commons 1.12.1.RELEASE  

请参阅https://github.com/paulvi/com.example.spring.findbyexample

使用Spring数据的Specification接口,我能够通过示例近似查询的使用。 这是一个PersonSpec类,它实现了Specification并需要一个“示例”人来设置Specification返回的Predicate

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

存储库很简单:

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

用法示例:

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