Frage

Ich möchte Datenzeitoperationen mit Hibernate HQL durchführen.

Ich möchte zwei Daten addieren und subtrahieren sowie 1 Jahr oder 1 Monat von einem bestimmten Datum subtrahieren.

Wie ist dies mit HQL im Ruhezustand möglich?

War es hilfreich?

Lösung

Siehe Performing Datum / Zeit Math In HQL? für ein Beispiel.

benutzerdefinierte SQL verwenden müssen Sie einen eigenen Hibernate Dialekt geschrieben und registrieren:

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

Andere Tipps

Sie müssen Ihren eigenen Dialekt erstellen. Etwas wie folgt aus:

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

In Hibernate / MySQL (mindestens) Sie können zu und von einem Unix-Zeitstempel umwandeln. Da der Unix-Zeitstempel eine ganze Zahl ist, können Sie eine ganze Anzahl von Sekunden, um es hinzuzufügen.

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

Es hat seine Grenzen, aber es ist viel einfacher, als die Ansätze oben.

Dies ist eine offene Frage in dem Ruhezustand. Ab Hibernate 3.3 gibt es keine Standardmethode Datum Vergleiche rein in HQL zu behandeln:

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

4.3 bietet Funktionen Hibernate Datum / Uhrzeit in HQL zuzugreifen, die sind:

current_timestamp() , current_date() , current_time()

können arithmetische Operationen durch verwaltet werden:

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

Disclaimer: Ich bin ein Java Anfänger

Ich konnte current_date() >= fromDate AND dateadd(day, -1, getdate()) <= toDate in einer HQL-Anweisung für eine Sybase db in Hibernate 3.5.3, verwenden, ohne Funktionen zu registrieren.

Anwendungsbeispiel des Ansatzes mit Dialekt für JPA + Hibernate 4.3.1 + MySQL 5

public class SampleMySQL5InnoDBDialect erweitert org.hibernate.dialect.MySQL5InnoDBDialect {

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

dann für Ihre Klasse mit Mapping-Anmerkung:

@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 hat toDate Feld vom Typ java.sql.Date und Dauer integer-Feld (in Tagen Dauer), und wir sind der Berechnung VonDatum = toDate - Dauer und alle Elemente ausgewählt werden, die VonDatum oder toDate innerhalb Intervall [startdate, endDate] .

Hibernate4.3 bietet native Funktionen, um auf Datums-/Zeitstempel zuzugreifen und arithmatische Operationen darauf durchzuführen

Hier ist der Link zur Dokumentation darüber, welche Ausdrücke in HQL verwendet werden können.Einige davon erwähne ich:So greifen Sie auf Datum/Uhrzeit zu:

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

Arithmetische Operationen können wie folgt ausgeführt werden.Diese Funktionen benötigen Zeit als Eingabe:

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

Man kann den absoluten Unterschied in HQL ermitteln durch

current_timestamp() - dateInstance

wobei dateInstance eine Definition haben kann

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

Das Ergebnis liegt in 0,1 Sekunden vor.Für eine absolute Differenz von 1 Sekunde ergibt der obige Ausdruck also das Ergebnis 10.

Eine Abfrage würde also wie folgt aussehen:

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

Posgresbenutzer ...

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

mit SQL Nutzung wie:

now() < dateadd(:mydate, '-1 day')
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top