springframework specification query org examples example domain data crudrepository complex java spring spring-data spring-data-jpa

java - specification - Spring Data JPA: Query by Example?



spring data specifications examples (3)

Esto ahora es posible con Spring Data. Echa un vistazo a http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example

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

Tenga en cuenta que esto requiere versiones muy recientes de 2016

<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.10.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> <version>1.12.1.RELEASE</version> </dependency>

vea https://github.com/paulvi/com.example.spring.findbyexample

Usando Spring Data JPA, ¿puedo hacer una consulta por ejemplo donde se use una instancia de entidad particular como criterio de búsqueda?

Por ejemplo (sin juego de palabras), si tengo una entidad de Person que se parece a:

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

Pude encontrar a todas las personas empleadas con un apellido de Smith nacido el 1 de enero de 1977 con un ejemplo:

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


Los datos de Spring se basan en JPA y EntityManager, no en Hibernate y Session, y como tal no tiene FindByExample fuera de la caja. Puede usar la creación automática de consultas de datos Spring y escribir un método en su repositorio con la siguiente firma:

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


Usando la interfaz de Specification Spring data, pude aproximar el uso de la consulta por ejemplo. Aquí hay una clase PersonSpec que implementa la Specification y requiere una persona de "ejemplo" para configurar el Predicate devuelto por la Specification :

public class PersonSpec implements Specification<Person> { private final Person example; public PersonSpec(Person example) { this.example = example; } @Override public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> cq, CriteriaBuilder cb) { List<Predicate> 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<Predicate> predicates, CriteriaBuilder cb) { return cb.and(predicates.toArray(new Predicate[0])); } }

El repositorio es simplemente:

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

Ejemplo de uso:

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