No Spring-data, Queries dinâmicas são feitas através de Specifications.
Consulta com criteria API
A Specification abstrai toda a complexidade da API criteria, facilitando o desenvolvimento de consultas dinâmicas.
Para utilizar a Specification é preciso que o repository herde de JpaSpecificationExecutor, e criar uma interface Specification que define as consultas.
@Repository
public interface FuncionarioRepository extends PagingAndSortingRepository<Funcionario, Integer>,
JpaSpecificationExecutor<Funcionario> {
public class SpecificationFuncionario {
public static Specification<Funcionario> nome(String nome){
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.like(root.get("nome"), "%"+nome+ "%");
}
public static Specification<Funcionario> cpf(String cpf){
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.equal(root.get("cpf"), cpf);
}
public static Specification<Funcionario> salario(Double salario){
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.greaterThan(root.get("salario"), salario);
}
public static Specification<Funcionario> dataContratacao(LocalDate dataContratacao){
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.greaterThan(root.get("dataContratacao"), dataContratacao);
}
}
Com isso, basta passar o método de consulta da Specification criado como parâmetro no método find().
funcionarioRepository.findAll(Specification.where(SpecificationFuncionario.nome(nomeString)));
Consulta dinâmica com Specification:
public void inicial(Scanner scanner){
System.out.println("Digite um nome");
String nome = scanner.next();
if(nome.equalsIgnoreCase("NULL")){
nome=null;
}
System.out.println("Digite um cpf");
String cpf = scanner.next();
if(nome.equalsIgnoreCase("NULL")){
cpf=null;
}
System.out.println("Digite o salário");
Double salario = scanner.nextDouble();
if(salario == 0){
salario=null;
}
System.out.println("Digite a data de contratacao");
String data = scanner.next();
LocalDate dataContratacao;
if(data.equalsIgnoreCase("NULL")){
dataContratacao=null;
}else{
dataContratacao = LocalDate.parse(data, formatter);
}
List<Funcionario> funcionarios = funcionarioRepository.findAll(Specification
.where(
SpecificationFuncionario.nome(nome)
.or(SpecificationFuncionario.cpf(cpf)
.or(SpecificationFuncionario.salario(salario)
.or(SpecificationFuncionario.dataContratacao(dataContratacao))))
));
funcionarios.forEach(System.out::println);
}
Specification
;