分頁是項目中經常會使用到的功能,我們可以自己手動在sql語句中進行分頁,但是這樣比較麻煩,Mybatis的PageHelper插件可以很好的幫助我們實現分頁功能。
添加maven依賴
在對應工程的pom.xml文件中添加
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.0.0</version>
</dependency>
配置攔截器
在mybatis-config.xml文件中添加分頁插件
<plugins>
<!-- com.github.pagehelper為PageHelper類所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 4.0.0以后版本可以不設置該參數 -->
<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>
參數配置選擇
列舉一些可能會用到某些參數的場景
- 分頁插件對RowBounds支持和Mybatis默認的方式是一致的,默認情況下不會進行count查詢,如果想在分頁查詢時進行count查詢,以及使用更強大的PageInfo類,需要設置該參數為true
- 如果覺得RowBounds中的兩個參數offset和limit不如pageNum和PageSize容易理解,可以設置offsetAsPageNum參數為true,offset會當成pageNum使用,limit和pageSize含義相同
- 如果即使使用了分頁,但是仍然想通過控制參數查詢出全部的結果,可以設置pageSizeZero為true,就可以通過設置pageSize=0或者RowBounds.limt=0查詢出全部的結果
- 如果在使用分頁查看列表式的數據時,希望用戶輸入的頁碼即使不在合法范圍內(第一頁到最后一頁之外),也能夠看到正確的結果,可以設置reasonable為true,這時如果pageNum<1會查詢第一頁,pageNum>總頁碼會查詢最后一頁
具體使用
RowBounds方式調用
使用這種調用方式時,用RowBounds參數進行分頁,侵入性最小,只是使用了這個參數,沒有增加其他內容。當分頁插件檢測到使用了RowBounds參數時,就會對該查詢進行物理分頁
public DaoQueryResultVO<MemberBasicEntity> queryList(MemberBasicEntity entity, int startPage, int pageSize) throws CcpException
{
SqlSession sqlSession = CcpDB.getInstance().getSession();
Map<String, Object> map = new HashMap<String, Object>();
try
{
String statement = TMemberDAO.NAME_SPACE + ".queryList";//映射sql的標識字符串
if (entity != null)
{
map.put("tMember", entity.getMember());
map.put("tClub", entity.getMainClub());
}
List<MemberBasicEntity> list = sqlSession.selectList(statement, map, new RowBounds(startPage, pageSize));
return new DaoQueryResultVO<MemberBasicEntity>(list);
}
catch (Exception e)
{
CcpLogger.getInstance().error(e, "TMemberDAO.queryList, " + map);
throw new CcpException(CcpErrorCode.ERROR_MEMBER_DAO_DB_ERROR, e);
}
finally
{
CcpDB.getInstance().closeSession();
}
}
因為分頁查詢結果返回的是一個Page對象,Page對象繼承自ArrayList,同時自身也擴展了屬性。但如果我們直接返回Page對象的話,在一些場景下會遇到問題,比如JSON處理Page類型的結果時,會被當成List來JSON格式化,就會丟棄Page對象的所有擴展屬性。所以這里我們將分頁的結果Page類型轉換成我們自己定義的一個類型DaoQueryResultVO,它繼承自PageInfo,包含了一個List屬性來保存分頁查詢出來的結果。PageInfo是插件提供給我們的,可以作為返回值,這里我們再用DaoQueryResultVO繼續封裝了一下,將PageInfo中的結果集由Page類型轉換為ArrayList類型
public class DaoQueryResultVO<T> extends PageInfo<T> implements Serializable
{
private static final long serialVersionUID = -6401449740378930924L;
private List<T> lstResultList;
public DaoQueryResultVO(List<T> list)
{
super(list);
if (getSize() >= 0)
{
lstResultList = new ArrayList<T>();
lstResultList.addAll(getList().subList(0, getSize()));
}
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return "DaoQueryResultVO [lstResultList=" + lstResultList + ", toString()=" + super.toString() + "]";
}
/**
* @return the lstResultList
*/
public List<T> getLstResultList()
{
return lstResultList;
}
}
PageHelper.startPage靜態方法調用
在需要進行分頁的方法前調用PageHelper.startPage靜態方法即可,緊跟在這個方法后的第一個查詢方法會被進行分頁