Рассматривали ли вы использование Технические характеристики ?
Используя спецификации, вы можете динамически генерировать часть 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()
к детали при поиске по имени, чтобы сделать поиск нечувствительным к регистру.