Подтвердить что ты не робот

Критерий спящего режима Год от даты

Im создает критерии спящего режима, которые будут проверять, действительно ли контракт действителен в течение года. Контракт имеет начало и дату окончания в качестве стандартного поля даты.

Поэтому, используя SQL-SERVER, я бы подумал что-то в строках этого SQL:

SELECT * FROM CONTRACT WHERE YEAR(startDate) <= ? AND YEAR(endDate) >= ?

Вопросительным знаком является данный год как целое число.

Итак, как преобразовать это в критерии спящего режима?

int year = 2011; //Just a testyear for example purposes.
DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class)
    .add(Restrictions.le("startDate", year))
    .add(Restrictions.ge("endDate", year));

Как вы можете видеть, я пропускаю бит, где я конвертирую дату в год, чтобы ее можно было сравнить. Естественно, мой код не работает, как есть.

Любое предложение о том, как получить желаемые результаты?

4b9b3361

Ответ 1

Кажется, что API напрямую не поддерживает то, что вы хотели, но есть обходное решение, которое вы можете рассмотреть.

Решение 1:

DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class)
    .add(Restrictions.le("startDate", toEndOfYear(year))
    .add(Restrictions.ge("endDate", toStartOfYear(year)));

public Date toStartOfYear(int year) {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.YEAR, year);
    calendar.set(Calendar.DAY_OF_YEAR, 0);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    return calendar.getTime();
}

public Date toEndOfYear(int year) {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.YEAR, year);
    calendar.set(Calendar.DAY_OF_YEAR, 0);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND,-1);
    return calendar.getTime();
}

Пример вывода двух методов:

System.out.println(toStartOfYear(2013));
System.out.println(toEndOfYear(2013));

Mon Dec 31 00:00:00 MYT 2012
Sun Dec 30 23:59:59 MYT 2012

Решение 2:

DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class)
    .add(Restrictions.sqlRestriction("YEAR(startDate) >= ? ", year,Hibernate.INTEGER))
    .add(Restrictions.sqlRestriction("YEAR(endDate) <= ? ", year,Hibernate.INTEGER));

Ответ 2

Используйте Restrictions.sqlRestriction, чтобы решить вашу проблему.

Ответ 3

Если вы используете JPA criteriaBuilder, вы можете использовать метод criteriaBuilder.function. Например.

contractRepository.findAll(new Specification<Contract>() {
   @Override
   public Predicate toPredicate(Root<Contract> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
     return cb.ge(cb.function("year", Integer.class, root.get(Contract_.endDate)), year);
   }
});

(я использую Spring Data Specifications в этом примере для запроса базы данных. contractRepository имеет тип JpaSpecificationExecutor)