web-dev-qa-db-fra.com

Comment effectuer des opérations de date en veille prolongée

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

Je veux ajouter et soustraire deux dates ainsi que je veux soustraire 1 an ou 1 mois d'une date donnée.

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

13
amar4kintu

Voir Calculs date/heure dans HQL? à titre d'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')") );
5
H2000

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)"));
      }
    }
8
z5h

C'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/HHHH2434

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(...)
4
Fred Haslam

Dans Hibernate/MySQL (au moins) Vous pouvez convertir vers et depuis un horodatage Unix. Puisque l'horodatage Unix est 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 c'est beaucoup plus facile que les approches ci-dessus.

4
Dean Mathieson

Disclaimer: Je suis un novice Java

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

1
foson

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

la classe publique SampleMySQL5InnoDBDialect étend org.hibernate.dialect.MySQL5InnoDBDialect {

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

puis 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 possède toDate champ de type Java.sql.Date et durée champ entier (durée en jours) et nous calculons fromDate = toDate - duration et sélectionnons toutes les entités qui ont fromDate ou toDate à l'intérieur de l'intervalle [date de début, date de fin] .

0
ydrozhdzhal

Les utilisateurs de Postgres ...

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

avec l'utilisation de SQL comme: 

now() < dateadd(:mydate, '-1 day')
0
Joseph Valerio

Hibernate4.3 fournit des fonctions natives pour accéder aux dates et aux horodatages et y effectuer des opérations arithmatiques.

Ici est le lien vers la documentation des expressions pouvant être utilisées dans HQL. Peu de choses 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 par

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 dans 0.1 secondes. Donc, pour une différence absolue de 1 seconde, l'expression ci-dessus donnera un résultat égal à 10.

Donc, une requête ressemblerait à ceci:

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