Hibernate 提供 HQL(物件導向查詢語言)與 Criteria API(QBC,Query By Criteria)兩種主流查詢方式。兩者各有優勢,盲目偏好其中一種會限制開發效率。本文從可讀性、動態組裝、多表關聯、效能調優、維護性五大維度深度對比,給出實戰選型建議。
// HQL
Query q = session.createQuery("from User u where u.id=2 and u.age=21 and u.name like 'J%'");
List list = q.list();
// Criteria
Criteria c = session.createCriteria(User.class);
list = c.add(Restrictions.eq("id", 2))
.add(Restrictions.eq("age", 21))
.add(Restrictions.like("name", "J%"))
.list();
Criteria 程式化構建,免拼接字串,編譯期檢查屬性名(搭配 Metamodel 更強)。
// HQL:需精通關聯路徑,字串長難維護
"from User u join u.accounts a where a.id=112546 and a.startDate='2008-8-30' and a.money=1000"
// Criteria:物件導向導航
Criteria c = session.createCriteria(User.class);
c.add(Restrictions.eq("id", 2))
.createCriteria("accounts", "a") // 關聯到 Account
.add(Restrictions.eq("a.id", 112546))
.add(Restrictions.eq("a.startDate", date))
.add(Restrictions.eq("a.money", 1000));
Criteria 在動態關聯(如可選關聯條件)極具優勢。
| 維度 | HQL | Criteria (QBC) |
|---|---|---|
| 靜態/簡單查詢 | ✅ 簡潔直觀,類 SQL 易上手 | 稍繁瑣,需建立 Criteria 物件 |
| 動態條件組裝 | ❌ 字串拼接易錯、防注入麻煩 | ✅ 程式化 add(),條件可選、可迴圈 |
| 多表關聯/投影 | ⚠️ 需手寫 join path,投影需 select new DTO | ✅ createCriteria/Projection 原生支援 |
| 效能調優 | ✅ 可直接複製到 DB 執行計畫分析 | ⚠️ 需開啟 show_sql 觀察生成 SQL |
| 類型安全/重構 | ❌ 字串屬性名,重構易漏改 | ✅ 搭配 Metamodel/Static Metamodel 編譯期檢查 |
| 分頁/排序 | setFirstResult/setMaxResults 同樣支援 | addOrder/orderBy 同樣支援 |
| 原生 SQL 映射 | createSQLQuery + addEntity/ResultTransformer | createSQLQuery + setResultTransformer |
User_.name)。// Repository 方法簽名統一回傳 List 或 Page
public List findByDynamicSpec(UserSpec spec) {
if (spec.isSimple()) return hqlTemplate.query(spec.toHql(), spec.getParams());
else return criteriaBuilder.build(spec).list();
}
將簡單查詢走 HQL,複雜動態查詢走 Criteria,Repository 封裝細節,上層無感知。
join fetch 或 setFetchMode(FetchMode.JOIN)。setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)。offset/limit 深分頁效能差,改用 Keyset Pagination(where id > lastId order by id limit 20)。setReadOnly(true) 或 @Transactional(readOnly=true) 關閉脏檢查提升效能。HQL 與 Criteria 不是非此即彼。成熟團隊應**兩者並用**,在 Repository 層封裝細節,根據查詢特性選擇最適工具。核心原則:靜態用 HQL,動態用 Criteria;調優看 SQL,重構靠類型安全。