2012-11-26 70 views
8

我想使用HQL從表中獲取已過期的實體。類似的東西:HQL中的日期操作

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

我不能得到如何做到這一點與HQL。我不想做額外的查詢,在Java代碼中處理日期等。這必須在HQL級別完成。

你能幫我嗎?

+0

什麼是數據庫? –

回答

10

根據您的數據庫,這可以非常簡單。 HQL支持內置的特定於供應商的功能和功能,它還支持通過註冊新功能來擴展方言(如果它們尚未被HQL支持)。

假設您正在使用SQLServer(或Sybase)。 SQLServer有一個名爲'DATEADD'的函數,可以很輕鬆地完成你喜歡的任務。格式爲:

DATEADD (datepart, number, date) 

您可以直接在HQL首先登記在自己的Hibernate方言的功能使用此功能。要做到這一點,你只需要擴展你目前使用的方言。這是一個非常簡單的過程。

首先,創建自己的方言類(用自己的數據庫供應商替換 'SQLServer2008Dialect'):

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的屬性)。

3

HQL不支持使用日期和時間的算術,所以在不擴展HQL的情況下是不可能的。最簡單的路徑可能是爲這樣的計算註冊數據庫供應商的SQL方言功能。其他可能性是執行並註冊interceptor(覆蓋的方法是onPrepareStatement),如果使用加號和減號的語法是首選。

當解決方案並不一定是純粹的HQL和時間從JVM主機是足夠簡單的解決方法是計算日期是在過去的10分鐘,把它作爲一個參數。如果數據庫時間是首選,那麼可以通過在單獨的查詢中查詢它,然後從中減去10分鐘來實現。