8

HQLを使用してテーブルから期限切れのエンティティを取得したい。そんな感じ:

select id, name from entity_table where date_creation + 10_minutes < current_time()

HQLでそれを行う方法がわかりません。余分なクエリを作成したくない、Javaコードで日付を処理するなど。これは、HQLレベルで実行する必要があります。

手伝ってくれませんか?

4

2 に答える 2

11

データベースによっては、これは簡単なことです。HQLは、組み込みのベンダー固有の機能をサポートします。また、HQLでまだサポートされていない場合は、新しい関数を登録することで方言を拡張する機能もサポートします。

SQLServer(またはSybase)を使用しているとしましょう。SQLServerには、「DATEADD」と呼ばれる関数があり、好きなことを非常に簡単に実行できます。形式は次のとおりです。

DATEADD (datepart, number, date)

この関数は、最初に独自のHibernate方言に登録することで、HQLで直接使用できます。これを行うには、現在使用している方言を拡張する必要があります。これは非常に単純なプロセスです。

まず、独自の方言クラスを作成します(「SQLServer2008Dialect」を独自のDBベンダーに置き換えます)。

public class MySQLServerDialect extends SQLServer2008Dialect {

  public MySQLServerDialect() {
    registerFunction("addminutes", new VarArgsSQLFunction(TimestampType.INSTANCE, "dateadd(minute,", ",", ")"));
  }

}

次に、この新しいクラスを使用するようにHibernate構成を変更します。

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    ...
    <property name="hibernate.dialect">com.mycompany.MySQLServerDialect</property>
    ...
</hibernate-configuration>

次に、関数を使用します。

select x from MyEntity x where addminutes(x.creationDate, 10) < current_time()

(これは、エンティティがMyEntityと呼ばれ、creation_dateフィールドがcreationDateというプロパティにマップされていることを前提としています)。

于 2012-11-26T21:49:47.123 に答える
3

HQLは日付と時刻の算術演算をサポートしていないため、HQLを拡張しないと不可能です。最も簡単な方法は、おそらくそのような計算のためにデータベースベンダーのSQL方言関数を登録することです。プラス記号とマイナス記号を使用した構文が望ましい場合は、インターセプターを実装して登録することもできます(オーバーライドする方法は)。onPrepareStatement

ソリューションが純粋にHQLである必要がなく、JVMホストからの時間が十分である場合、最も簡単なソリューションは、過去10分である日付を計算し、それを引数として指定することです。データベース時間を優先する場合は、別のクエリでクエリを実行してから10分ずつデクリメントすることで実現できます。

于 2012-11-26T20:25:21.423 に答える