1. 程式人生 > >2017.12.14 Mybatis物理分頁外掛PageHelper的使用(一)

2017.12.14 Mybatis物理分頁外掛PageHelper的使用(一)

參考來自:

1.物理分頁和邏輯分頁

1 邏輯分頁 : 邏輯分頁指的是將資料庫中所有資料全部取出,然後通過Java程式碼控制分頁邏輯。 
2 物理分頁 : 物理分頁指的是在SQL查詢過程中實現分頁,依託與不同的資料庫廠商,實現也會不同。

2.需求

現在使用的是邏輯分頁,因為出現了效能問題,考慮將其變為物理分頁。ps:專案中使用的ibatis的方式,具體的舊程式碼後面會有 。

3.實際使用

3.0 Spring中mybatis的配置

使用PageHelper也不會影響的部分,但為了說明還是列出來和mybatis相關的檔案內容:

1     <!-- MyBatis配置 -->
2 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 3 <property name="dataSource" ref="dataSource"/> 4 <property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml"/> 5 <!-- 自動掃描entity目錄, 省掉Configuration.xml裡的手工配置
--> 6 <property name="typeAliasesPackage" value="classpath:com/baosight/**/entity"/> 7 <!-- 顯式指定Mapper檔案位置 --> 8 <property name="mapperLocations" value="classpath:sql/**/*.xml"/> 9 </bean>

3.1 舊程式碼

來自BaseService.query()方法。主要邏輯是,當curPage=null或curRowNum=null時,不進行分頁。否則進行分頁處理。

重點程式碼如下:

 1         Integer curPage = (Integer) paramInfo.get("curPage");
 2         Integer curRowNum = (Integer) paramInfo.get("curRowNum");
 3 
 4         List<JSONObject> resultArr = new ArrayList<JSONObject>();
 5         try {
 6             if (curPage == null || curRowNum == null) {
 7                 resultArr = sqlSessionTemplate.selectList(querySql, daoEntity);
 8             } else {
 9                 resultArr = sqlSessionTemplate.selectList(querySql, daoEntity,
10                         new RowBounds((curPage - 1) * curRowNum, curRowNum));
11             }
12         } catch (Exception e) {
13             e.printStackTrace();
14             paramInfo.put("status", Constants.EXECUTE_FAIL);
15             paramInfo.put("returnMsg", "查詢出錯,請檢查SQL語句!");
16             return paramInfo;
17         }

其他引數相關的程式碼如下:

即這裡的querySql、countSql對應的是一個名稱空間下的某方法。

1         paramInfo.put("querySql", "GlobalMessage.querybatch");
2         paramInfo.put("countSql", "GlobalMessage.countbatch");
3         paramInfo.put("DaoEntity", "com.lyh.entity.GlobalMessage");

GlobalMessage.xml的名稱空間如下:

1 <mapper namespace="GlobalMessage">

queryBathch如下:顯然是不帶任何有關limit和offset的sql語句。

 1     <select id="querybatch" parameterType="com.lyh.entity.GlobalMessage"
 2             resultType="com.alibaba.fastjson.JSONObject">
 3         select * from t_global_message12         where
13         1 = 1
14         <if test="messageId != null">
15             and MESSAGE_ID = #{messageId}
16         </if>
17         <if test="messageKey != null and messageKey != ''" >
18             and MESSAGE_KEY in (${messageKey})
19         </if>
26         <if test="messageLan != null">
27             and MESSAGE_LAN = #{messageLan}
28         </if>
29         <if test="messageEnable != null">
30             and MESSAGE_ENABLE = #{messageEnable}
31         </if>
59     </select>

3.2 新程式碼

(1)pom.xml
1        <dependency>
2             <groupId>com.github.pagehelper</groupId>
3             <artifactId>pagehelper</artifactId>
4             <version>4.1.0</version>
5         </dependency>
(2)mybatis的配置檔案SqlMapConfig.xml

<plugins>標籤內的為新增部分,即註冊PageHelper。

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <properties resource="project.properties" />
 7     <settings>
 8         <setting name="logPrefix" value="dao." />
 9     </settings>
19     <plugins>
20         <!-- com.github.pagehelper為PageHelper類所在包名 -->
21         <plugin interceptor="com.github.pagehelper.PageHelper">
22             <property name="dialect" value="postgresql"/>
27             <!--設定為true時,如果pagesize=0或者rowbounds.limit=0就會查詢出所有的結果-->
28             <property name="pageSizeZero" value="true"/>
29             <property name="reasonable" value="true"/>
30         </plugin>
31     </plugins>
37 </configuration>
(3)程式碼變動
 1         Integer curPage = (Integer) paramInfo.get("curPage");
 2         Integer curRowNum = (Integer) paramInfo.get("curRowNum");
 3 
 4         PageInfo<JSONObject> pageResult;
 5         try {
 6             if (curPage == null || curRowNum == null) {//不分頁,查詢出所有
 7                 curRowNum = 0;
 8                 curPage = 0;
 9             }
10 
11             PageHelper.startPage(curPage, curRowNum);
12 
13             //PageHelper.startPage(pageIndex,pageSize);//當前頁碼,每頁大小
14             List<JSONObject> list = sqlSessionTemplate.selectList(querySql, daoEntity,
15                     new RowBounds((curPage-1)*curRowNum, curRowNum));
16             pageResult = new PageInfo<>(list);
17             pageResult.setList(list);
18         } catch (Exception e) {
19             e.printStackTrace();
20             paramInfo.put("status", Constants.EXECUTE_FAIL);
21             paramInfo.put("returnMsg", "查詢出錯,請檢查SQL語句!");
22             return paramInfo;
23         }

4.效果比對

使用pageHelper之前,查詢時的sql語句示例如下:

1 DEBUG dao.GlobalMessage.queryBatch - ==>  Preparing: select * from t_global_message where 1 = 1 
2 DEBUG dao.GlobalMessage.queryBatch - ==> Parameters: 

使用pageHelper之後,輸出的sql已經拼接了limit和offset:

1 DEBUG dao.GlobalMessage.queryBatch - ==>  Preparing: select * from t_global_message where 1 = 1 limit ? offset ?
2 DEBUG dao.GlobalMessage.queryBatch - ==> Parameters: 10 0

當在程式中傳遞curPage或者curRowNum為null時,根據程式碼,curPage和curRowNum被置為了0,此時仍然使用pageHelper,sql語句沒有拼接limit和offset,將所有資料都查詢出來了:

1 DEBUG dao.GlobalMessage.queryBatch - ==>  Preparing: select * from t_global_message where 1 = 1 
2 DEBUG dao.GlobalMessage.queryBatch - ==> Parameters: