首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 實戰:使用 HQL 與 Criteria API 查詢時間區間資料

     編輯:Java 相關知識

前言

在企業級應用開發中,依據時間區間篩選資料是極為常見的需求。本文將透過實際代碼示範,說明如何在 Hibernate 中運用 HQL(Hibernate Query Language)與 QBC(Query By Criteria)兩種主流查詢方式,高效完成日期範圍的資料檢索。

資料庫日期型別儲存的考量

資料庫對日期時間的儲存格式各有差異(如 Oracle 的 DATE、MySQL 的 DATETIME、SQL Server 的 DATETIME2 等)。為了確保跨資料庫的相容性,團隊討論後傾向於採用字串格式統一儲存,或在應用層統一轉換為 java.sql.Date / java.sql.Timestamp 再持久化,避免因資料庫遷移導致的查詢邏輯錯誤。

方案一:HQL 參數化查詢

HQL 寫法直觀,贴近 SQL 語法,支援命名參數,能有效防止 SQL 注入。以下示範查詢 2009-03-24 至 2009-03-26 之間的記錄:

Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();

Date begin = java.sql.Date.valueOf("2009-03-24");
Date end   = java.sql.Date.valueOf("2009-03-26");

String hql = "from A a where a.date > :beginTime and a.date <= :endTime";
List<A> result = session.createQuery(hql)
    .setTimestamp("beginTime", begin)
    .setTimestamp("endTime", end)
    .list();

for (A a : result) {
    System.out.println(a.getId());
    System.out.println(a.getTitle());
    System.out.println(a.getDate());
}
tx.commit();
session.close();

關鍵點:使用 setTimestamp 而非 setDate,可保留時分秒精度,避免邊界條件遺漏資料。

方案二:Criteria API(QBC)動態組裝

Criteria API 以物件導向方式建構查詢,適合動態條件組合,程式碼更具型別安全與重構友善性:

Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();

Date begin = java.sql.Date.valueOf("2009-03-24");
Date end   = java.sql.Date.valueOf("2009-03-26");

Criteria criteria = session.createCriteria(AbstractA.class);
Criterion criterion = Restrictions.between("date", begin, end); // 包含邊界
List<A> result = criteria.add(criterion).list();

for (A a : result) {
    System.out.println(a.getId());
    System.out.println(a.getTitle());
    System.out.println(a.getDate());
}
tx.commit();
session.close();

注意:Hibernate 5.2 起 Expression 已棄用,建議改用 org.hibernate.criterion.Restrictions。

最佳實踐建議

  • 統一使用 UTC 時間儲存,應用層負責時區轉換。
  • 索引優化:對查詢頻繁的日期欄位建立 B-Tree 索引。
  • 大量資料分頁時,搭配 setFirstResult/setMaxResults 避免記憶體溢位。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved