Mybatis分頁插件-PageHepler的使用
使用方法
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#1-%E5%BC%95%E5%85%A5%E5%88%86%E9%A1%B5%E6%8F%92%E4%BB%B6 1. 引入分頁插件
引入分頁插件一共有下面2種方式,推薦使用Maven方式,這種方式友善更新。
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#1-%E5%BC%95%E5%85%A5jar%E5%8C%85 1). 引入Jar包
如果你想使用本項目的jar包而不是直接引入類,你可以在這裡下載下傳各個版本的jar包(點選Download下的jar即可下載下傳)
- https://oss.sonatype.org/content/repositories/releases/com/github/pagehelper/pagehelper/
- http://repo1.maven.org/maven2/com/github/pagehelper/pagehelper/
由于使用了sql解析工具,你還需要下載下傳jsqlparser.jar(這個檔案完全獨立,不依賴其他):
- http://repo1.maven.org/maven2/com/github/jsqlparser/jsqlparser/0.9.1/
- http://git.oschina.net/free/Mybatis_PageHelper/attach_files
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#2-%E4%BD%BF%E7%94%A8maven 2). 使用maven
添加如下依賴:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.6.4</version>
</dependency>
當使用maven中央庫中的快照版(帶
"-SNAPSHOT"
的版本)時,需要在pom.xml中添加如下配置:
<repositories>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#2-%E5%9C%A8mybatis%E9%85%8D%E7%BD%AExml%E4%B8%AD%E9%85%8D%E7%BD%AE%E6%8B%A6%E6%88%AA%E5%99%A8%E6%8F%92%E4%BB%B6- 2. 在Mybatis配置xml中配置攔截器插件:
<!--
plugins在配置檔案中的位置必須符合要求,否則會報錯,順序如下:
properties?, settings?,
typeAliases?, typeHandlers?,
objectFactory?,objectWrapperFactory?,
plugins?,
environments?, databaseIdProvider?, mappers?
-->
<plugins>
<!-- com.github.pagehelper為PageHelper類所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
<!-- 該參數預設為false -->
<!-- 設定為true時,會将RowBounds第一個參數offset當成pageNum頁碼使用 -->
<!-- 和startPage中的pageNum效果一樣-->
<property name="offsetAsPageNum" value="true"/>
<!-- 該參數預設為false -->
<!-- 設定為true時,使用RowBounds分頁會進行count查詢 -->
<property name="rowBoundsWithCount" value="true"/>
<!-- 設定為true時,如果pageSize=0或者RowBounds.limit = 0就會查詢出全部的結果 -->
<!-- (相當于沒有執行分頁查詢,但是傳回結果仍然是Page類型)-->
<property name="pageSizeZero" value="true"/>
<!-- 3.3.0版本可用 - 分頁參數合理化,預設false禁用 -->
<!-- 啟用合理化時,如果pageNum<1會查詢第一頁,如果pageNum>pages會查詢最後一頁 -->
<!-- 禁用合理化時,如果pageNum<1或pageNum>pages會傳回空資料 -->
<property name="reasonable" value="true"/>
<!-- 3.5.0版本可用 - 為了支援startPage(Object params)方法 -->
<!-- 增加了一個`params`參數來配置參數映射,用于從Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用預設值 -->
<!-- 不了解該含義的前提下,不要随便複制該配置 -->
<property name="params" value="pageNum=start;pageSize=limit;"/>
</plugin>
</plugins>
這裡的
com.github.pagehelper.PageHelper
使用完整的類路徑。
其他五個參數說明:
- 增加
屬性,使用時必須指定該屬性,可選值為dialect
,oracle
mysql
mariadb
sqlite
hsqldb
postgresql
,沒有預設值,必須指定該屬性。sqlserver
-
屬性,預設值為offsetAsPageNum
,使用預設值時不需要增加該配置,需要設為false
時,需要配置該參數。當該參數設定為true
時,使用true
分頁時,會将RowBounds
參數當成offset
使用,可以用頁碼和頁面大小兩個參數進行分頁。pageNum
-
rowBoundsWithCount
false
true
true
分頁會進行count查詢。RowBounds
-
pageSizeZero
false
true
時,如果true
或者pageSize=0
就會查詢出全部的結果(相當于沒有執行分頁查詢,但是傳回結果仍然是RowBounds.limit = 0
類型)。Page
-
reasonable
false
時,需要配置該參數。具體作用請看上面配置檔案中的注釋内容。true
- 為了支援
方法,增加了一個startPage(Object params)
參數來配置參數映射,用于從Map或ServletRequest中取值,可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用預設值。params
重要提示:
當
offsetAsPageNum=false
的時候,由于PageNum問題,
RowBounds
查詢的時候reasonable會強制為false。使用
PageHelper.startPage
方法不受影響。
另外使用
RowBounds
在這種情況下傳回的
Page
對象由于沒有正确的
pageNum
屬性,是以也不能使用
PageInfo
處理。
如果你不了解為什麼,可以看這樣一個例子:查詢
offset=7,limit=10
,這個時候
pageNum=?
,這種情況沒法計算
pageNum
,沒法判斷目前是第幾頁。
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#3-%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9%E9%85%8D%E7%BD%AE%E8%BF%99%E4%BA%9B%E5%8F%82%E6%95%B0 3. 如何選擇配置這些參數
單獨看每個參數的說明可能是一件讓人不爽的事情,這裡列舉一些可能會用到某些參數的情況。
首先
dialect
屬性是必須的,不需要解釋。其他的參數一般情況下我們都不必去管,如果想了解何時使用合适,你可以參考以下場景:
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#%E5%9C%BA%E6%99%AF%E4%B8%80 場景一
如果你仍然在用類似ibatis式的命名空間調用方式,你也許會用到
rowBoundsWithCount
,分頁插件對
RowBounds
支援和Mybatis預設的方式是一緻,預設情況下不會進行count查詢,如果你想在分頁查詢時進行count查詢,以及使用更強大的
PageInfo
類,你需要設定該參數為
true
。
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#%E5%9C%BA%E6%99%AF%E4%BA%8C 場景二
如果你仍然在用類似ibatis式的命名空間調用方式,你覺得RowBounds中的兩個參數
offset,limit
不如
pageNum,pageSize
容易了解,你可以使用
offsetAsPageNum
參數,将該參數設定為
true
後,
offset
會當成
pageNum
使用,
limit
和
pageSize
含義相同。
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#%E5%9C%BA%E6%99%AF%E4%B8%89 場景三
如果覺得某個地方使用分頁後,你仍然想通過控制參數查詢全部的結果,你可以配置
pageSizeZero
為
true
,配置後,如可以通過設定
pageSize=0
RowBounds.limit = 0
就會查詢出全部的結果。
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#%E5%9C%BA%E6%99%AF%E5%9B%9B 場景四
如果你分頁插件使用于類似分頁檢視清單式的資料,如新聞清單,軟體清單,你希望使用者輸入的頁數不在合法範圍(第一頁到最後一頁之外)時能夠正确的響應到正确的結果頁面,那麼你可以配置
reasonable
true
,這時如果
pageNum<1
會查詢第一頁,如果
pageNum>總頁數
會查詢最後一頁。
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#4-spring%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95 4. Spring配置方法
首先需要在Spring中配置
org.mybatis.spring.SqlSessionFactoryBean
。然後配置配置Mybatis的具體配置有兩種方式,一種是用mybatis預設的xml配置,另一種就是完全使用spring的屬性配置方式。
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#1-mybatis%E9%BB%98%E8%AE%A4%E7%9A%84xml%E9%85%8D%E7%BD%AE 1.mybatis預設的xml配置
配置
configLocation
屬性指向上面的
mybatis-config.xml
檔案。有關分頁插件的配置都在
mybatis-config.xml
,具體配置内容參考上面的
mybatis-config.xml
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#2-%E4%BD%BF%E7%94%A8spring%E7%9A%84%E5%B1%9E%E6%80%A7%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F 2.使用spring的屬性配置方式
注意:請不用同時使用spring配置方式和mybatis-config.xml配置方式,隻需要選擇其中一個就行。配置多個分頁插件時,會抛出異常提示。
分頁插件配置錯誤:請不要在系統中配置多個分頁插件(使用Spring時,mybatis-config.xml和Spring配置方式,請選擇其中一種,不要同時配置多個分頁插件)!
使用spring的屬性配置方式,可以使用
plugins
屬性像下面這樣配置:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations">
<array>
<value>classpath:mapper/*.xml</value>
</array>
</property>
<property name="typeAliasesPackage" value="com.isea533.ssm.model"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
dialect=hsqldb
reasonable=true
</value>
</property>
</bean>
</array>
</property>
</bean>
屬性配置按照上面的方式配置,每個配置獨立一行即可。
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#5-%E5%A6%82%E4%BD%95%E5%9C%A8%E4%BB%A3%E7%A0%81%E4%B8%AD%E4%BD%BF%E7%94%A8 5. 如何在代碼中使用
閱讀前後請注意看
重要提示首先該分頁插件支援以下兩種調用方式:
//第一種,RowBounds方式的調用
List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(1, 10));
//第二種,Mapper接口方式的調用,推薦這種使用方式。
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
下面分别對這兩種方式進行詳細介紹
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#1-rowbounds%E6%96%B9%E5%BC%8F%E7%9A%84%E8%B0%83%E7%94%A8 1). RowBounds方式的調用
List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(1, 10));
使用這種調用方式時,你可以使用RowBounds參數進行分頁,這種方式侵入性最小,我們可以看到,通過RowBounds方式調用隻是使用了這個參數,并沒有增加其他任何内容。
分頁插件檢測到使用了RowBounds參數時,就會對該查詢進行實體分頁。
關于這種方式的調用,有兩個特殊的參數是針對
RowBounds
的,你可以參看上面的
注:不隻有命名空間方式可以用RowBounds,使用接口的時候也可以增加RowBounds參數,例如:
//這種情況下也會進行實體分頁查詢
List<Country> selectAll(RowBounds rowBounds);
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#2- 2). PageHelper.startPage
靜态方法調用
PageHelper.startPage
在你需要進行分頁的Mybatis方法前調用
PageHelper.startPage
靜态方法即可,緊跟在這個方法後的第一個Mybatis查詢方法會被進行分頁。
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#%E4%BE%8B%E4%B8%80- 例一:
SqlSession sqlSession = MybatisHelper.getSqlSession();
CountryMapper countryMapper = sqlSession.getMapper(CountryMapper.class);
try {
//擷取第1頁,10條内容,預設查詢總數count
PageHelper.startPage(1, 10);
//緊跟着的第一個select方法會被分頁
List<Country> list = countryMapper.selectIf(1);
assertEquals(2, list.get(0).getId());
assertEquals(10, list.size());
//分頁時,實際傳回的結果list類型是Page<E>,如果想取出分頁資訊,需要強制轉換為Page<E>,
//或者使用PageInfo類(下面的例子有介紹)
assertEquals(182, ((Page) list).getTotal());
} finally {
sqlSession.close();
}
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#%E4%BE%8B%E4%BA%8C- 例二:
SqlSession sqlSession = MybatisHelper.getSqlSession();
CountryMapper countryMapper = sqlSession.getMapper(CountryMapper.class);
try {
//擷取第1頁,10條内容,預設查詢總數count
PageHelper.startPage(1, 10);
//緊跟着的第一個select方法會被分頁
List<Country> list = countryMapper.selectIf(1);
//後面的不會被分頁,除非再次調用PageHelper.startPage
List<Country> list2 = countryMapper.selectIf(null);
//list1
assertEquals(2, list.get(0).getId());
assertEquals(10, list.size());
//分頁時,實際傳回的結果list類型是Page<E>,如果想取出分頁資訊,需要強制轉換為Page<E>,
//或者使用PageInfo類(下面的例子有介紹)
assertEquals(182, ((Page) list).getTotal());
//list2
assertEquals(1, list2.get(0).getId());
assertEquals(182, list2.size());
} finally {
sqlSession.close();
}
http://git.oschina.net/free/Mybatis_PageHelper/blob/master/wikis/HowToUse.markdown#%E4%BE%8B%E4%B8%89-%E4%BD%BF%E7%94%A8 例三,使用 PageInfo
的用法:
PageInfo
//擷取第1頁,10條内容,預設查詢總數count
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectAll();
//用PageInfo對結果進行包裝
PageInfo page = new PageInfo(list);
//測試PageInfo全部屬性
//PageInfo包含了非常全面的分頁屬性
assertEquals(1, page.getPageNum());
assertEquals(10, page.getPageSize());
assertEquals(1, page.getStartRow());
assertEquals(10, page.getEndRow());
assertEquals(183, page.getTotal());
assertEquals(19, page.getPages());
assertEquals(1, page.getFirstPage());
assertEquals(8, page.getLastPage());
assertEquals(true, page.isFirstPage());
assertEquals(false, page.isLastPage());
assertEquals(false, page.isHasPreviousPage());
assertEquals(true, page.isHasNextPage());