Hibernate通過Cirteria求翻頁插件的總記錄數

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


發佈了72 篇原創文章 · 獲贊 12 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章