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