作為資深 ORM 框架,Hibernate 提供了豐富多樣的查詢機制,從原生 SQL 到面向對象的 HQL、QBC(Criteria API)、QBE(Example Query),滿足不同場景需求。本文系統匯總八種主流查詢方式,助你靈活選型。
HQL 面向對象,語法類似 SQL 但操作的是實體類與屬性。
Hibernate 4.1+ 已不推薦,易因參數順序導致錯誤。
String hql = "from UserPO where name = ? and passwd = ?"; Query query = session.createQuery(hql); query.setParameter(0, userPO.getName()); query.setParameter(1, userPO.getPasswd());
可讀性強,順序不敏感,參數名需與 HQL 中一致。
String hql = "from UserPO where name = :userName and passwd = :userPwd";
Query query = session.createQuery(hql);
query.setParameter("userName", userPO.getName());
query.setParameter("userPwd", userPO.getPasswd());
符合 JPA 規範,注意 setParameter 參數為字串索引。
String hql = "from UserPO where name = ?1 and passwd = ?2";
Query query = session.createQuery(hql);
query.setParameter("1", userPO.getName());
query.setParameter("2", userPO.getPasswd());
直接傳入 POJO,Hibernate 自動匹配同名屬性,**僅支持命名參數占位符**。
String hql = "from UserPO where name = :name and passwd = :passwd"; Query query = session.createQuery(hql); query.setProperties(userPO); // 自動注入 name、passwd
注意:以上 1-4 種方式,HQL 均可替換為原生 SQL(
createSQLQuery),用法相通。
Criteria API 完全面向對象,無字串拼接風險,重構友好,是笔者最推薦的方式。
Criteria criteria = session.createCriteria(UserPO.class);
criteria.add(Restrictions.eq("name", userPO.getName()));
criteria.add(Restrictions.eq("passwd", userPO.getPasswd()));
return criteria.list();
傳入一個屬性已設置的實例,自動忽略 null 值,極適合多條件可選查詢。
Criteria criteria = session.createCriteria(UserPO.class); criteria.add(Example.create(userPO)); // 自動匹配非空屬性 return criteria.list();
QBC 核心輔助類:
Restrictions:等值、範圍、Like、In、IsNull 等條件構建Order:Order.asc("name") / Order.desc("id") 排序Projections:投影查詢、統計(count/sum/avg)、分組(groupProperty)DetachedCriteria 無需 Session 即可構建查詢條件,可跨層傳遞(如 Service 層構建,DAO 層執行),降低耦合。
DetachedCriteria dc = DetachedCriteria.forClass(UserPO.class);
dc.add(Restrictions.eq("name", userPO.getName()));
// 傳遞到 DAO 層
Criteria criteria = dc.getExecutableCriteria(session);
return criteria.list();
Criteria 與 Query 均支持 setFirstResult(起始行,0-based)與 setMaxResults(每頁條數)。
// Criteria 分頁 Criteria criteria = session.createCriteria(UserPO.class); criteria.setFirstResult(4); // 第 5 條開始 criteria.setMaxResults(3); // 取 3 條 return criteria.list(); // HQL/SQL 分頁同理 Query query = session.createQuery(hql); query.setFirstResult(4).setMaxResults(3);
| 場景 | 推薦方式 | 理由 |
|---|---|---|
| 簡單固定條件查詢 | HQL (命名參數) | 可讀性高,易維護 |
| 動態多條件組合查詢 | QBC (Criteria + Restrictions) | 類型安全,重構友好,避免字串拼接 |
| 表單可選字段查詢 | QBE (Example) | 自動忽略空值,代碼極簡 |
| 跨層傳遞查詢條件 | DetachedCriteria | 解耦 Service 與 DAO |
| 複雜統計/分組/投影 | QBC (Projections) | 面向對象聚合操作 |
| 極致性能/特殊 SQL | Native SQL | 繞過 Hibernate 方言限制 |
蘿蔔青菜各有所愛,團隊應統一規範 1-2 種主力查詢方式,兼顧代碼一致性與開發效率。掌握這八種姿勢,應對 Hibernate 99% 的查詢場景綽綽有餘。