Question

Je souhaite effectuer des opérations de temps de données en utilisant hibernate HQL.

Je veux ajouter et soustraire deux dates de même que je veux soustraire un an ou un mois d'une date donnée.

Comment est-ce possible d'utiliser HQL en veille prolongée?

Était-ce utile?

La solution

Voir Calculs de date / heure d'exécution dans HQL? pour un exemple.

Pour utiliser SQL personnalisé, vous devez écrire votre propre dialecte de veille prolongée et vous enregistrer:

registerFunction("weekday", 
  new SQLFunctionTemplate(Hibernate.INTEGER, "to_char(?1,'D')") );

Autres conseils

Vous devez créer votre propre dialecte. Quelque chose comme ce qui suit:

public class MyDialect extends MySQLInnoDBDialect{
      public myDialect() {
      super();
      registerFunction("date_add_interval", new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));
      }
    }

Dans Hibernate / MySQL (au moins) Vous pouvez convertir depuis et vers un horodatage Unix. Le timestamp unix étant un entier, vous pouvez lui ajouter un nombre entier de secondes.

FROM_UNIXTIME(UNIX_TIMESTAMP(date)+ (allowedTimeWindow*86400)) as deadline

Il a des limites mais il est beaucoup plus facile que les approches ci-dessus.

Ceci est un problème en suspens dans Hibernate. Depuis Hibernate 3.3, il n’existait aucun moyen standard de gérer les comparaisons de dates uniquement en HQL:

https://hibernate.atlassian.net/browse/HHH-2434

Hibernate 4.3 offre des fonctions pour accéder à la date / heure dans HQL, à savoir:

current_timestamp() , current_date() , current_time()

Les opérations arithmétiques peuvent être gérées par:

SECOND(...) , MINUTE(...) , HOUR(...) , DAY(...) , MONTH(...) , YEAR(...)

Avertissement: je suis un novice en Java

J'ai pu utiliser current_date() >= fromDate AND dateadd(day, -1, getdate()) <= toDate dans une instruction HQL contre une base de données Sybase dans Hibernate 3.5.3, sans enregistrer de fonction.

Exemple d'utilisation de l'approche avec dialecte pour JPA + Hibernate 4.3.1 + MySQL 5

public class SampleMySQL5InnoDBDialect étend org.hibernate.dialect.MySQL5InnoDBDialect {

public SampleMySQL5InnoDBDialect() {
    super();
    registerFunction("date_sub_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "date_sub(?1, interval ?2 day)"));
}

alors pour votre classe avec l'annotation de mappage:

@NamedQuery(name = "SampleEntity.getSampleEntitiesForGapOverlapCalculations", query = "from SampleEntity as se where "
    + "((se.toDate between :startDate and :endDate) or (date_sub_days(se.toDate, se.duration) between :startDate and :endDate)) order by se.toDate asc, se.duration desc")

SampleEntity a un champ toDate de type java.sql.Date et durée champ entier (durée en jours) et nous calculons deDate = àDate - durée et sélectionnons toutes les entités qui possèdent deDate ou toDate à l'intérieur de l'intervalle [startDate, endDate] .

Hibernate4.3 fournit des fonctions natives pour accéder aux dates et aux horodatages et effectuer des opérations arithmatiques sur celles-ci

Ici est le lien vers la documentation des expressions pouvant être utilisées dans HQL. Quelques-uns dont je parle: Pour accéder à la date / heure:

current_date(), current_time(), and current_timestamp()

Les opérations arithmétiques peuvent être effectuées en suivant. Ces fonctions prennent le temps en entrée:

second(...), minute(...), hour(...), day(...), month(...), and year(...)

On peut obtenir une différence absolue en HQL en

current_timestamp() - dateInstance

où dateInstance peut avoir une définition

@Column(name = "updated_at")
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date updatedAt;

Le résultat est en 0.1 seconde. Donc, pour une différence absolue de 1 seconde, l'expression ci-dessus donnera un résultat égal à 10.

Donc, une requête ressemblerait à:

select t from Table t where (current_timestamp() - updatedAt)>600

Utilisateurs de Postgres ...

registerFunction("dateadd", new SQLFunctionTemplate(StandardBasicTypes.DATE, "(?1 + INTERVAL ?2)"));

avec une utilisation SQL telle que:

now() < dateadd(:mydate, '-1 day')
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top