Обмисляли ли сте използването на Спецификации ?
Използвайки спецификации, можете динамично да генерирате WHERE
част от заявка за пролетни данни. За да използвате спецификации с вашите JPA заявки за пролетни данни, ще трябва да разширите org.springframework.data.jpa.repository.JpaSpecificationExecutor
интерфейс. Така че потребителското ви хранилище може да изглежда така:
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}
Вашият метод на търсене може да изглежда така
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);
}
Първо започваме с добавяне на name LIKE %text%
част от израза where.
След това проверяваме дали стойността на text
променливата може да бъде преобразувана в long
. Ако може, извличаме дългата стойност от низа и я добавяме към заявката where.
Последно проверяваме дали text
променливата може да бъде преобразувана в булево. Ако може, добавяме и тази проверка към заявката.
Например, ако стойността на text
променливата е test1 където ще бъде частта
WHERE name LIKE '%test1%;
Ако стойността на text
променливата е true тогава частта where ще бъде
WHERE name LIKE '%true%' OR is_active = true;
И накрая, ако стойността на text
променливата е 12 тогава частта where ще бъде
WHERE name LIKE '%12%' OR id = 12;
Забележка: Добавих cb.lower(root.get("name"))
и text.toLowerCase()
към частта, когато търсим по име, за да направим търсенето нечувствително към главни и малки букви.