No Spring-data, Queries dinâmicas são feitas através de Specifications.

Consulta com criteria API

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

Untitled

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

O que foi aprendido?