Web開發中,經常會使用到翻頁插件,翻頁插件一般含有符合多條件的總記錄數,之前通過用criteria.list().size()求解時,是相當笨的方法,當數據到20W的時候,僅僅調用一個查詢列表就反應65S,而且對內存消耗也是很驚人的。
沒辦法只好換思路。
思路一:請過JDBC來求解:好處執行速度快,但是要自己維護連接池,還要拼SQL,尤其是多條件查詢的時候,很容易出錯。
思路二:通過Query來求解,速度會比JDBC慢些,好處是Hibernate可以幫你維護數據庫的連接,弊端是要拼接SQL,容易出錯。
思路三:還是Criteria來求解,好處有:繞開SQL,通過Java API來操作數據庫;之前求多條件查詢就通過Criteria來實現,只需要維護一處。弊端可能會慢,但是在幾十萬條規模情境下慢不了多少。
思路三代碼:
/**
* 符合【多條件查詢】的組合記錄數
* @param entity
* @return
*/
public int getRecords(T entity){
Criteria criteria = createCriteria(entity);//約束條件
criteria.setProjection(Projections.rowCount());
return ((Long)criteria.uniqueResult()).intValue();
}
/**
* 多條件查詢時
* 返回含有部分結果集的Page對象
* @param page
* @param entity
* @return
*/
public Page<T> listPage(Page page, T entity){
page.setTotalCount(getRecords(entity));//符合條件的總記錄數
Criteria criteria = createCriteria(entity);//約束條件
//起始位置
criteria.setFirstResult((page.getPageNo()-1)*page.getPageSize());
criteria.setMaxResults(page.getPageSize());//結果集大小
page.setResult(criteria.list());
return page;
}
通過JUnit4i單元測試
@Test
public void testGetRecords() throws Exception {
// entity.setContent("d7");
StopWatch watch = new StopWatch();
page.setPageNo(2);
watch.start();
int result = dao.getRecords(entity);
watch.stop();
System.out.println("符合要求的記錄數: " + result);
System.out.println("查詢時間: " + watch.getTotalTimeSeconds() + " 秒");
}
運行結果:
下面繼續:添加條件
Junit測試方法testGetRecords()的entity.setContent("d7")取消註釋;
運行結果
直接通過SQL執行:
select count(*) from news t where content like '%d7%';
執行結果
數據規模爲28W+,執行時間差爲0.145S