web-dev-qa-db-ja.com

Oracleで時間を無視しながらHQLを使用して日付をクエリする

Hibernateを使用して特定の日のすべてのエントリを検索する必要があるテーブル(Oracle 9以降)があります。エントリにはタイムスタンプがあります(データタイプは 'date')。一部のエントリには時刻があり、他のエントリには日付のみがあります。これは私が変更できない他のアプリケーションの出力であるため、変更できません。 SQLでは、次のように記述します。

SELECT * FROM table WHERE trim(table.date) = to_date('11.06.2009')

私が探している日付のすべてのエントリを取得します。 HQLを使用してHibernateでこれを実行する方法を知りたいと思っていました。 HibernateでSQLクエリを使用できることはわかっていますが、これはあまりクリーンではないようです。これを行う方法はありますか?可能であれば、この方法は、タイムスタンプがデータ型となるOracle以外のデータベースでも機能します。

16
Thomas Lötzer

HQLに2つの制約を入れることができます。1つは検索する日付の開始日以上を指定し、もう1つは翌日未満を指定します。

つまり.

table.date >=11.06.2009 AND table.date < 11.07.2009

HQL(およびSQL)では、次のことも可能です。

table.date between 11.06.2009 AND 11.07.2009

betweenは常に包括的であること、つまり両方であることに注意してください>=および<=それぞれ。
ここでbetweenの詳細: http://www.coding-dude.com/wp/Java/hibernate-Java/hibernate-hql-between-expression/ =

15
tschaible

これを解決するには2つの方法があると思います。

  1. criteria クエリを使用して、 SQLRestriction を追加します。制限は "trim({alias} .date)=?"という形式になります。ここでの問題は、Oracle(または他のDBMS)での入力パラメーターの正しいタイプへの変換です。必要な(休止状態)タイプをパラメーターとして指定できますが、これがデータベースに依存している場合は、ハードコーディングされます。

  2. hibernateマッピングで を使用します。マッピングは次のようになります。

    <class name = "Person"> 
 <property name = "birthDay" formula = "trim(birthDay)" />
 </ class>

これで、Hibernateのタイピングシステムを使用して、次のようなJavaオブジェクトとの比較を使用できます。

s.createCriteria(Person.class)
 .add(Restrictions.eq("birthDay", new Java.sql.Date(System.currentTimeMillis())))
 .list()

両方のソリューションで発生する1つの問題は、trim関数がデータベースで使用できない可能性があることです。これに対する解決策(HSQLDBでのテスト中など)は、クラスパステストにimport.sqlを配置し(これはHibernateによって自動的に選択されます)、そこにプロシージャまたは関数を作成します。あなたもすることができます Alter table Person add column birthDay timestampをそのファイルに追加して、生成されたスキーマを機能させます。

2
Maarten Winkels

CustomHQLの場合、truncキーワードを試すことができます

例:

SELECT T0.FirstName as FirstName ,T0.LastLoginDate as LastLoginDate  FROM User T0
WHERE (trunc(T0.LastLoginDate) >= :LastLoginDate) ORDER BY T0.LastLoginDate 

注:どこ:LastLoginDateはパラメータです。

これは私にとってはトリックです。

2
user565390