В задаче по реализации фильтра, столкнулся с следующей проблемой. У фильтра есть некоторое колличество полей, которые в случае если пользователь оставил их пустыми, на сервер, в объект фильтра, прилетают как null
. А при запросе в базу, мне надо получить объект org.springframework.data.jpa.domain.Specifications
, который представит этот фильтр на SQL
территории. Я хотел использовать следующую конструкцию для формирования объекта Specifications
:
public Page<Phone> list(@NonNull Filter filter) {
Specifications<Phone> specifications = where(equal("id", filter.getId()))
.and(isBetween("regDate", filter.getRegFrom(), filter.getRegTo()))
.and(contain("operatorAccPassword", filter.getOpPassword()))
.and(contain("operatorAccLogin", filter.getOpLogin()))
.and(contain("operatorName", filter.getOpName()))
.and(contain("number", filter.getNumber()))
.and(equal("status", filter.getStatus()))
.and(contain("note", filter.getNote()));
return phoneRepository.findAll(specifications, filter.getPageable());
}
public interface PhoneRepository extends CrudRepository<Phone, Integer>, JpaSpecificationExecutor<Phone> {
class Specifications {
public static Specification<Phone> equal(@NonNull String column, @NotNull Object value) {
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.equal(root.get(column), value);
}
public static Specification<Phone> contain(@NonNull String column, @NotNull String value) {
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.like(root.get(column), value);
}
public static Specification<Phone> isBetween(@NonNull String column, @NonNull Timestamp from, @NonNull Timestamp to) {
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.between(root.get(column), from, to);
}
}
}
Но загвоздка в том, что если в .and(contain("fieldName", value)
в качестве значения попадает null
, то соответственно запрос требует null
в значении соответствующего столбца, для того чтобы считать кортеж подпадающем под условие, а мне необходимо сделать так, чтобы поле просто исключалось из списка условий, если оно равно null
.
Конечно в самом крайнем случае можно создать отдельный Specifications для каждого поля и наделать кучу if else но хочется сделать нормально. Подскажите пожалуйста как можно выйти из положения имея в виду что на слудующем шаге мне придется учитывать тот факто что таких репозиториев у меня будет много под каждый вид сущьности, не только Phone
и методы static Specification<Phone> equal(...)
по сути повторяются.
В общем, буду весьма признателен за любые конструктивные соображения на этот счет.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Хочу сделать Longpoll запрос на сервер vk для бота, но сперва нужно получить ключ и адрес сервера, https://vkcom/dev/groups
Как выполнить последовательно эти два метода? получается что они выполняются одновременно, а нужно чтобы сначала прямоугольник перемещался...