提供了兩個核心方法:getList(業務入口,構建條件)和 findAll(執行分頁 HQL 查詢)。
public List getList(String startTime, String endTime, String mc, Pager pager) {
String where = " ";
where = where + " and " + TypeChange.DateBetweenSql("a.riQi", startTime, endTime);
if (!TypeChange.toNotNullDao(mc).equals("")) {
where = where + " and a.mingCheng like '%" + TypeChange.toNotNullNullDao(mc) + "%'";
}
return this.findAll(where, pager);
}
private List<Test> findAll(String where, Pager pager) {
String hSql = " From Test a where 1=1 " + where + " order by id ";
pager.setRowCount(getAllRowCount(hSql));
Session sess = this.getSessionFactory().openSession();
try {
Query query = sess.createQuery(hSql);
query.setFirstResult(pager.getFirstResult());
query.setMaxResults(pager.getPageSize());
return query.list();
} finally {
sess.close();
}
}
String where = " ":初始化為包含一個空格的字符串,確保後續拼接 and ... 時語法正確(避免 where 1=1and...)。TypeChange.DateBetweenSql("a.riQi", startTime, endTime):工具方法生成日期範圍條件,如 a.riQi between '2023-01-01' and '2023-12-31'。拼接後 where = " and a.riQi between ..."。TypeChange.toNotNullDao(mc):工具方法處理 null/空字符串,返回安全字符串。like '%...%':模糊查詢,匹配包含關鍵字的記錄。where 可能為 " and a.riQi between ... and a.mingCheng like '%xxx%'" 或僅含日期條件。String hSql = " From Test a where 1=1 " + where + " order by id ":
From Test a:HQL 查詢實體 Test,別名 a。where 1=1:經典技巧,確保後續拼接的 and ... 語法始終合法,即使 where 為空也無語法錯誤。order by id:按主鍵排序,保證分頁結果穩定。pager.setRowCount(getAllRowCount(hSql)):執行單獨的計數查詢(select count(*) ...)獲取總記錄數,設置到分頁對象,用於計算總頁數。Session sess = this.getSessionFactory().openSession():打開新 Session(非當前線程綁定的 getCurrentSession),需手動關閉。Query query = sess.createQuery(hSql):創建 HQL 查詢對象。query.setFirstResult(pager.getFirstResult()):設置起始行(offset),如第 2 頁每頁 10 條 → firstResult=10。query.setMaxResults(pager.getPageSize()):設置最大返回行數(limit)。return query.list():執行查詢並返回實體列表。finally { sess.close() }:**必須在 finally 中關閉 Session**,防止連接洩漏,即使查詢拋異常也能釋放資源。where 直接拼接字符串,mc 經 toNotNullDao 處理但未做參數化。建議改用**命名參數**:query.setParameter("mc", "%" + mc + "%"),HQL 中寫 and a.mingCheng like :mc。
getCurrentSession() 配合 @Transactional,由容器管理生命週期,無需手動 open/close。getAllRowCount 應構造 select count(a) From Test a where 1=1 ... 而非查全表再數。List 原始類型,建議改為 List<Test>。這段代碼展示了經典的 **Hibernate 手動分頁查詢模式**:動態拼接 HQL 片段 → 計總數 → 開 Session → 設置分頁參數 → 執行查詢 → 關 Session。理解 where 1=1 技巧、setFirstResult/setMaxResults 分頁機制、以及 finally 保證資源釋放,是掌握 Hibernate 底層操作的關鍵。實際項目中建議優先使用 Spring Data JPA / MyBatis-Plus 等框架內置的分頁能力,減少樣板代碼與風險。