Hibernateで日付操作を実行する方法
質問
Hibernate HQLを使用してデータ時間操作を実行したい。
2つの日付を加算および減算し、特定の日付から1年または1か月を減算します。
HibernateでHQLを使用してこれをどのように可能にしますか?
解決
参照 HQLで日付/時刻の計算を実行しますか 例です。
カスタムSQLを使用するには、独自の休止状態の方言を作成して登録する必要があります。
registerFunction("weekday",
new SQLFunctionTemplate(Hibernate.INTEGER, "to_char(?1,'D')") );
他のヒント
独自の方言を作成する必要があります。次のようなもの:
public class MyDialect extends MySQLInnoDBDialect{
public myDialect() {
super();
registerFunction("date_add_interval", new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));
}
}
Hibernate / MySQLで(少なくとも) Unixタイムスタンプとの間で変換できます。 UNIXタイムスタンプは整数であるため、整数の秒数を追加できます。
FROM_UNIXTIME(UNIX_TIMESTAMP(date)+ (allowedTimeWindow*86400)) as deadline
制限はありますが、上記のアプローチよりもはるかに簡単です。
これはHibernateの未解決の問題です。 Hibernate 3.3の時点では、純粋にHQLで日付比較を処理する標準的な方法はありません。
https://hibernate.atlassian.net/browse/HHH-2434
Hibernate 4.3は、HQLの日付/時刻にアクセスするための関数を提供します。
current_timestamp() , current_date() , current_time()
算術演算は次によって管理できます:
SECOND(...) , MINUTE(...) , HOUR(...) , DAY(...) , MONTH(...) , YEAR(...)
免責事項:私はJava初心者です
関数を登録せずに、Hibernate 3.5.3のSybase dbに対するHQLステートメントでcurrent_date() >= fromDate AND dateadd(day, -1, getdate()) <= toDate
を使用できました。
JPA + Hibernate 4.3.1 + MySQL 5用の方言を使用したアプローチの使用例
パブリッククラスSampleMySQL5InnoDBDialectはorg.hibernate.dialect.MySQL5InnoDBDialectを拡張します{
public SampleMySQL5InnoDBDialect() {
super();
registerFunction("date_sub_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "date_sub(?1, interval ?2 day)"));
}
その後、マッピングアノテーションを使用したクラスの場合:
@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 には、タイプjava.sql.Dateおよび duration の toDate フィールドがあります>整数フィールド(日数)および fromDate = toDate-duration を計算し、 fromDate を持つすべてのエンティティを選択していますstrong>または toDate 間隔 [startDate、endDate] 内。
Hibernate4.3は、日付/タイムスタンプにアクセスし、それらに対して算術演算を実行するネイティブ関数を提供します
ここは、HQLで使用できる式のドキュメントへのリンクです。 私が言及しているものはほとんどありません: 日付/時刻にアクセスするには:
current_date(), current_time(), and current_timestamp()
算術演算は次の方法で実行できます。これらの関数は、入力として時間を取ります:
second(...), minute(...), hour(...), day(...), month(...), and year(...)
次の方法でHQLの絶対差を取得できます
current_timestamp() - dateInstance
dateInstanceは定義を持つことができます
@Column(name = "updated_at")
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date updatedAt;
結果は0.1秒です。したがって、1秒の絶対差に対して、上記の式の結果は10になります。
したがって、クエリは次のようになります。
select t from Table t where (current_timestamp() - updatedAt)>600
Postgresユーザー...
registerFunction("dateadd", new SQLFunctionTemplate(StandardBasicTypes.DATE, "(?1 + INTERVAL ?2)"));
次のようなSQLの使用:
now() < dateadd(:mydate, '-1 day')