it-swarm.xyz

Java: функция даты JPQL для добавления периода времени к другой дате

SELECT x FROM SomeClass
WHERE x.dateAtt BETWEEN CURRENT_DATE AND (CURRENT_DATE + 1 MONTH)

В приведенном выше выражении JPQL SomeClass имеет memebr dateAttr, который является Java.util.Date и имеет аннотацию @Temporal(javax.persistence.TemporalType.DATE).

Мне нужен способ сделать бит (CURRENT_DATE + 1 MONTH) - он явно неверен в своем текущем состоянии - но не могу найти документ с функцией date для JPQL.

Может кто-нибудь указать мне направление документа, который документирует функции даты JPQL (а также как сделать этот конкретный запрос)?

23
bguiz

Если у вас уже есть объект даты + 1 месяц, вы можете сделать что-то вроде этого:

public List findEmployees(Date endDate) {
  return entityManager.createQuery(
    "SELECT e from Employee e WHERE e.startDate BETWEEN ?1 AND ?2")
    .setParameter(1,new Date(), TemporalType.DATE)
    .setParameter(2,endDate, TemporalType.DATE).getResultList();
}

Это, однако, требует, чтобы даты были действительны заранее.

ОБНОВЛЕНИЕ

Если вы всегда хотите следующий месяц, вы можете использовать JodaTime , у которого отличный и простой API .. Вы можете изменить свой запрос следующим образом:

//Get next month
DateTime dt = new DateTime();
entityManager.createQuery(
"SELECT e from Employee e WHERE e.startDate BETWEEN ?1 AND ?2")
.setParameter(1,new Date(), TemporalType.DATE)
.setParameter(2,dt.plusMonths(1).toDate(), TemporalType.DATE).getResultList();
17
Shervin Asgari

Стандартный JPQL не поддерживает такие операции с датами. Вам придется либо использовать собственный запрос, либо выполнить вычисления на стороне Java.

18
Pascal Thivent

Или используйте commons-lang вместо jodatime:

entityManager.createQuery(
    "SELECT e from Employee e WHERE e.startDate BETWEEN ?1 AND ?2"
)
.setParameter(1,new Date(), TemporalType.DATE)
.setParameter(2,DateUtils.addMonths(new Date(), 1), TemporalType.DATE)
.getResultList();

Но я знаю, что это не то, что вы спрашиваете, и я почти уверен, что это не может быть сделано только в JPQL, вам придется либо передать параметр, либо использовать собственный именованный запрос

4
Sean Patrick Floyd

Dears,

я использую данные весны, объект сохраняет createDate как datetime, и в репозитории вот так: 

@Query(value="SELECT t FROM MyEntity t WHERE t.createdDate Between ?1 and ?2")
public List<MyEntity> findAllBetweenDates(Calendar from, Calendar to);

поэтому я не могу использовать:

setParameter(1,new Date(), TemporalType.DATE

в бэкэнде я использую следующее:

    //to set zero of hours,minutes,seconds and milliseconds
    fromCalendar.set(Java.util.Calendar.HOUR, 0);
    fromCalendar.set(Java.util.Calendar.MINUTE, 0);
    fromCalendar.set(Java.util.Calendar.SECOND, 0);
    fromCalendar.set(Java.util.Calendar.MILLISECOND, 0);

    toCalendar.set(Java.util.Calendar.HOUR, 0);
    toCalendar.set(Java.util.Calendar.MINUTE, 0);
    toCalendar.set(Java.util.Calendar.SECOND, 0);
    toCalendar.set(Java.util.Calendar.MILLISECOND, 0);
    // add 1 days and decrease 1 millisecond
    toCalendar.add(Java.util.Calendar.DAY_OF_MONTH, 1);
    toCalendar.add(Java.util.Calendar.MILLISECOND, -1);

    allEntities = myEntityRepository.findAllBetweenDates(fromCalendar, toCalendar);
}

и работает нормально.

0
Hazim