#java #criteria-api
#java #критерии-api
Вопрос:
кто-нибудь знает, как создать фильтр с помощью CriteriaBuilder?
Я создаю API, и мне нужно создать фильтр для метода списка. В базе данных SQL Server столбец представляет собой smalldatetime, а SQL-запрос, который решает мою проблему, выглядит так:
SELECT * from TABLE
where DAY(COLUMN) LIKE 10 AND MONTH(COLUMN) LIKE 5
У меня есть класс DTO, который я использую для фильтрации в своем запросе:
public class MyDTOFilter {
private Integer day;
private Integer month;
}
Например, если a даст какой-то день = 5, я хотел бы получить этот ответ:
«2020-01-05»
«2020-02-05»
«2019-10-05″…
Если указать оба, например, месяц = 1 и день = 10, я хотел бы получить этот ответ:
«2020-01-10»
«2019-01-10»
«2018-01-10″…
Как я могу это сделать, используя CriteriaBuilder на Java?
Спасибо вам всем.
Ответ №1:
Поскольку CriteriaBuilder не имеет специализированных функций базы данных, вам необходимо вызвать эти функции по имени:
// DAY(COLUMN) returns an int
criteriaBuilder.function("DAY", Integer.class, "COLUMN")
// or, with JPA metamodel
criteriaBuilder.function("DAY", Integer.class, Entity_.column)
Результат должен быть примерно таким:
public List<LocalDate> findDates(int day, int month) {
CriteriaQuery<LocalDate> query = criteriaBuilder.createQuery(LocalDate.class);
Root<Entity> root = query.from(Entity.class);
query.select(root.get(Entity_.column));
List<Predicate> predicates = new ArrayList<>();
ParameterExpression<Integer> dayParameter = null;
ParameterExpression<Integer> monthParameter = null;
if (day > 0) {
dayParameter = criteriaBuilder.parameter(Integer.class);
predicates.add(
criteriaBuilder.equal(
criteriaBuilder.function("DAY", Integer.class, root.get(Entity_.column)),
dayParameter ));
}
if (month > 0) {
monthParameter = criteriaBuilder.parameter(Integer.class);
predicates.add(
criteriaBuilder.equal(
criteriaBuilder.function("MONTH", Integer.class, root.get(Entity_.column)),
monthParameter ));
}
if (!predicates.isEmpty()) {
query.where(criteriaBuilder.and(
predicates.toArray(new Predicate[predicates.size()])));
}
TypedQuery<GregorianCalendar> typedQuery = getEntityManager().createQuery(query);
if (dayParameter != null) {
typedQuery.setParameter(dayParameter, day);
}
if (monthParameter != null) {
typedQuery.setParameter(monthParameter, month);
}
return typedQuery.getResultList();
}
Комментарии:
1. Я понимаю, в чем тут дело, я использую спецификацию<T> и попытался помочь вам, но я получаю другую ошибку:
code org.springframework.dao.InvalidDataAccessApiUsageException: Unable to locate Attribute with the the given name
code` Вот суть метода: link Мой класс DateFilter имеет два атрибута: частный целочисленный день; частный целочисленный месяц; Вы знаете, как это сделать?2. Прокомментировал там @Neil