web-dev-qa-db-fra.com

Java: fonction de date JPQL pour ajouter une période à une autre date

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

Dans l'instruction JPQL ci-dessus, SomeClass a une memebr dateAttr, qui est un Java.util.Date et une annotation @Temporal(javax.persistence.TemporalType.DATE).

J'ai besoin d'un moyen de faire le bit (CURRENT_DATE + 1 MONTH) - il est évidemment faux dans son état actuel - mais je ne trouve pas le doc avec la fonction de date pour JPQL.

Quelqu'un peut-il m'indiquer un document qui documente les fonctions de date JPQL (et comment effectuer cette requête particulière)?

23
bguiz

Si vous avez déjà un objet de date qui est + 1 mois, vous pouvez faire quelque chose comme ceci:

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();
}

Cela nécessite cependant que les dates soient valides à l'avance.

METTRE À JOUR

Si vous voulez toujours le mois prochain, vous pouvez utiliser JodaTime qui a une grande et facile api . Vous pouvez ensuite modifier votre requête comme ceci:

//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 standard ne supporte pas de telles opérations sur les dates. Vous devrez soit utiliser une requête native, soit effectuer le calcul du côté Java.

18
Pascal Thivent

Ou utilisez commons-lang au lieu de 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();

Mais je sais que ce n’est pas ce que vous demandez et je suis à peu près sûr que cela ne peut pas être fait uniquement en JPQL.

4

Dears,

j'utilise des données de printemps, l'entité enregistre la createdDate en tant que date/heure et dans le référentiel comme ceci: 

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

donc je ne peux pas utiliser:

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

dans le haricot backend, j'utilise ce qui suit:

    //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);
}

et ça marche bien.

0
Hazim