Você já considerou o uso de Especificações ?
Usando especificações, você pode gerar dinamicamente o
WHERE
parte de uma consulta de dados de mola. Para usar especificações com suas consultas JPA de dados de mola, você terá que estender o org.springframework.data.jpa.repository.JpaSpecificationExecutor
interface. Então, seu repositório de usuário pode ficar assim:public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}
Seu método de pesquisa pode ser assim
public List<User> getAllFilterByString(String text) {
if(StringUtils.isEmpty(text))
return userRepository.findAll();
Specification<User> specification =
(root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.like(cb.lower(root.get("name")), "%"+text.toLowerCase()+"%"));
//check if the text value can be casted to long.
//if it is possible, then add the check to the query
try {
long longValue = Long.valueOf(text);
predicates.add(cb.equal(root.get("id"), longValue));
}
catch (NumberFormatException e) {
//do nothing, the text is not long
}
//check if the text can be casted to boolean
//if it is possible, then add the check to the query
Boolean value = "true".equalsIgnoreCase(text) ? Boolean.TRUE :
"false".equalsIgnoreCase(text) ? Boolean.FALSE : null;
if(value != null) {
predicates.add(cb.equal(root.get("isActive"), value));
}
return cb.or(predicates.toArray(new Predicate[] {}));
};
return userRepository.findAll(specification);
}
Primeiro começamos adicionando o
name LIKE %text%
parte da expressão where. Em seguida, verificamos se o valor do
text
variável pode ser convertida para long
. Se puder, obtemos o valor longo da string e o adicionamos à consulta where. Por último, verificamos se o
text
variável pode ser convertida em boolean. Se puder, adicionamos essa verificação à consulta também. Por exemplo, se o valor do
text
variável é teste1 a parte onde será WHERE name LIKE '%test1%;
Se o valor do
text
variável é true então a parte onde será WHERE name LIKE '%true%' OR is_active = true;
Finalmente, se o valor do
text
variável é 12 então a parte onde será WHERE name LIKE '%12%' OR id = 12;
Observação: Eu adicionei
cb.lower(root.get("name"))
e text.toLowerCase()
à parte quando pesquisamos por nome para tornar a pesquisa insensível a maiúsculas e minúsculas.