日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PageHelper 关闭COUNT(0)查询 以及PageHelper 的分页原理分析

發布時間:2025/3/12 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PageHelper 关闭COUNT(0)查询 以及PageHelper 的分页原理分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

pagehelper 關閉count(0)查詢 以及pagehelper的分頁原理分析

情景再現:在給移動端提供分頁查詢數據接口時,知道他們不需要總條數。但是使用pagehelper 分頁查詢打印的sql總是會查詢兩次,先統計條數,在進行列表查詢。對于有點強迫癥的我來說,很不爽。于是開始查資料追源碼。

于是找到了pagehelper的分頁對象: com.github.pagehelper.Page; 其中一個屬性count默認是true,默認會執行count查詢/*** 包含count查詢*/private boolean count = true;

1.關閉count()查詢

在執行分頁列表查詢前添加
PageHelper.startPage(page, size, false);

成功關閉count()查詢
PageHelper中的其他方法也可以關閉count()查詢,請讀者自行查閱;

2.拋出問題

本來事情到此已經完美解決,但是因為我們是自己定義了一個Page對象(其實就是com.github.pagehelper.Page,寫在本地的一個pojo)。查詢的條件封裝在一個對象中,并繼承自定義的Page,然后嘗試在自定義的Page中設置count為false,發現并不能生效。

3.原因查找

1)在com.github.pagehelper.util.PageObjectUtil類中下面方法中找到了設置count屬性的邏輯,
調用getParamValue(paramsObject, “count”, false);

public static <T> Page<T> getPageFromObject(Object params, boolean required) {......//count查詢Object _count = getParamValue(paramsObject, "count", false);if (_count != null) {page.setCount(Boolean.valueOf(String.valueOf(_count)));}//排序if (hasOrderBy) {page.setOrderBy(orderBy.toString());}//分頁合理化Object reasonable = getParamValue(paramsObject, "reasonable", false);if (reasonable != null) {page.setReasonable(Boolean.valueOf(String.valueOf(reasonable)));}//查詢全部Object pageSizeZero = getParamValue(paramsObject, "pageSizeZero", false);if (pageSizeZero != null) {page.setPageSizeZero(Boolean.valueOf(String.valueOf(pageSizeZero)));} }

2)從下圖中的debug中可以看出getParamValue(paramsObject, “count”, false); 返回null,修改count屬性失敗

3)分析問題
使用PageHelper設置屬性就能生效,是因為PageHelper設置屬性的時候創建了一個本地的Page對象,并存儲到本地。如下面的代碼:

類位置:com.github.pagehelper.page.PageMethod/*** 開始分頁** @param pageNum 頁碼* @param pageSize 每頁顯示數量* @param count 是否進行count查詢*/public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count) {return startPage(pageNum, pageSize, count, null, null);}....../*** 開始分頁** @param pageNum 頁碼* @param pageSize 每頁顯示數量* @param count 是否進行count查詢* @param reasonable 分頁合理化,null時用默認配置* @param pageSizeZero true且pageSize=0時返回全部結果,false時分頁,null時用默認配置*/public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {Page<E> page = new Page<E>(pageNum, pageSize, count);page.setReasonable(reasonable);page.setPageSizeZero(pageSizeZero);//當已經執行過orderBy的時候Page<E> oldPage = getLocalPage();if (oldPage != null && oldPage.isOrderByOnly()) {page.setOrderBy(oldPage.getOrderBy());}setLocalPage(page);return page;}

在進行判斷是否進行count查詢的時候查找的是PageHelper中的page對象,所以設置的屬性能夠生效

2)com.github.pagehelper.PageInterceptor中有是否執行count查詢的條件@Overridepublic Object intercept(Invocation invocation) throws Throwable {......//判斷是否需要進行 count 查詢if (dialect.beforeCount(ms, parameter, rowBounds)) {String countMsId = msId + countSuffix;Long count;//先判斷是否存在手寫的 count 查詢........}} 類位置:com.github.pagehelper.dialect.AbstractHelperDialect#beforeCount@Overridepublic boolean beforeCount(MappedStatement ms, Object parameterObject, RowBounds rowBounds) {Page page = getLocalPage();return !page.isOrderByOnly() && page.isCount();}

page.isOrderByOnly() boolean類型 默認false,page.isCount()默認true;所以修改了page.isCount()為false
后,能夠關閉count(0)查詢

4.討論一個問題,為什么使用本地對象也能夠使PageHelper 進行分頁?

有下面方法可知:只要參數中有pageSize和pageNum,PageHelper 就會自動創建PageHelper 中的pege對象 實現分頁邏輯。
路徑:com.github.pagehelper.util.PageObjectUtil#getPageFromObject

public static <T> Page<T> getPageFromObject(Object params, boolean required) { ......try {Object _pageNum = getParamValue(paramsObject, "pageNum", required);Object _pageSize = getParamValue(paramsObject, "pageSize", required);if (_pageNum == null || _pageSize == null) {if(hasOrderBy){Page page = new Page();page.setOrderBy(orderBy.toString());page.setOrderByOnly(true);return page;}return null;}pageNum = Integer.parseInt(String.valueOf(_pageNum));pageSize = Integer.parseInt(String.valueOf(_pageSize));} catch (NumberFormatException e) {throw new PageException("分頁參數不是合法的數字類型!");}Page page = new Page(pageNum, pageSize);...... }

5.PageHelper 實現分頁的原理

在執行分頁sql拼接時,在sql后拼接limit進行分頁,在調用方言的時候拼接分頁參數

1)路徑:com.github.pagehelper.PageInterceptor#intercept......//判斷是否需要進行分頁查詢if (dialect.beforePage(ms, parameter, rowBounds)) {//生成分頁的緩存 keyCacheKey pageKey = cacheKey;//處理參數對象parameter = dialect.processParameterObject(ms, parameter, boundSql, pageKey);//調用方言獲取分頁 sqlString pageSql = dialect.getPageSql(ms, boundSql, parameter, rowBounds, pageKey);BoundSql pageBoundSql = new BoundSql(configuration, pageSql, boundSql.getParameterMappings(), parameter);//設置動態參數for (String key : additionalParameters.keySet()) {pageBoundSql.setAdditionalParameter(key, additionalParameters.get(key));}//執行分頁查詢resultList = executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, pageKey, pageBoundSql);} else {//不執行分頁的情況下,也不執行內存分頁resultList = executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, boundSql);}.......2)路徑:com.github.pagehelper.dialect.helper.MySqlDialect#getPageSql@Overridepublic String getPageSql(String sql, Page page, CacheKey pageKey) {StringBuilder sqlBuilder = new StringBuilder(sql.length() + 14);sqlBuilder.append(sql);if (page.getStartRow() == 0) {sqlBuilder.append(" LIMIT ? ");} else {sqlBuilder.append(" LIMIT ?, ? ");}pageKey.update(page.getPageSize());return sqlBuilder.toString();}


PageHelper自定義count(*)查詢

因數據量太大,使用分頁插件PageHelper解析sql,執行sql時會count一遍總計錄數,此時會將數據庫卡死;

使用分頁插件執行,會嵌套一層SELECT COUNT(*) FROM (主sql) tmp_count

SELECT count(*) FROM (SELECTc.company_name,c.company_type,...FROM company cINNER JOIN t_seller ts ON ts.city_site_id = c.city_site_id....WHERE c.city_site_id = 1) tmp_count

希望自定義個cout方法統計總記錄數,刪減不必要的表關聯、字段,
應如何入手?

最新版的PageHelper支持自定義count,參考https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/Changelog.md#504—2017-08-01

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的PageHelper 关闭COUNT(0)查询 以及PageHelper 的分页原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。