Avez-vous envisagé l'utilisation de Spécifications ?
En utilisant les spécifications, vous pouvez générer dynamiquement le WHERE
partie d'une requête de données de printemps. Afin d'utiliser les spécifications avec vos requêtes JPA de données de printemps, vous devrez étendre le org.springframework.data.jpa.repository.JpaSpecificationExecutor
interface. Ainsi, votre référentiel d'utilisateurs pourrait ressembler à ceci :
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}
Votre méthode de recherche pourrait ressembler à ceci
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);
}
Nous commençons d'abord par ajouter le name LIKE %text%
partie de l'expression where.
Ensuite, nous vérifions si la valeur du text
la variable peut être convertie en long
. Si c'est le cas, nous extrayons la valeur longue de la chaîne et l'ajoutons à la requête where.
Enfin, nous vérifions si le text
variable peut être convertie en booléen. Si c'est le cas, nous ajoutons également cette vérification à la requête.
Par exemple, si la valeur du text
la variable est test1 la partie où sera
WHERE name LIKE '%test1%;
Si la valeur du text
la variable est vraie puis la partie où sera
WHERE name LIKE '%true%' OR is_active = true;
Enfin, si la valeur du text
la variable est 12 puis la partie où sera
WHERE name LIKE '%12%' OR id = 12;
Remarque : J'ai ajouté cb.lower(root.get("name"))
et text.toLowerCase()
à la partie lorsque nous recherchons par nom afin de rendre la recherche insensible à la casse.