[DB][MyBatis]利用mybatis-paginator實現分頁(目前看到MyBatis下最好的分頁實現)

來源:互聯網
上載者:User

利用mybatis-paginator實現分頁

 

1、mybatis-paginator簡介

mybatis-paginator是gethub上的一個開源項目、用於java後台擷取分頁資料、該開源項目還提供一個列表組件(mmgrid)用於前端展示。

該開源項目地址:https://github.com/miemiedev

 

2、該開源項目的使用說明:

Maven中加入依賴:

<dependencies>  ...    <dependency>        <groupId>com.github.miemiedev</groupId>        <artifactId>mybatis-paginator</artifactId>        <version>1.2.10</version>    </dependency>  ...</dependencies>


Mybatis設定檔添加分頁外掛程式:  

<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPE configuration  PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"  "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"><configuration>    <plugins>        <plugin interceptor="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor">            <propertyname="dialectClass"value="com.github.miemiedev.mybatis.paginator.dialect.OracleDialect"/>        </plugin>     </plugins></configuration>


建立一個查詢,內容可以是任何Mybatis運算式,包括foreach和if等:

<selectid="findByCity"resultType="map">    select * from TEST_USER where city = #{city};</select>


Dao中的方法或許是這樣(用介面也是類似):

public List findByCity(String city, PageBounds pageBounds){    Map<String, Object> params =new HashMap<String, Object>();    params.put("city",city);    returngetSqlSession().selectList("db.table.user.findByCity", params, pageBounds);}


調用方式(分頁加多列排序):

int page = 1; //頁號int pageSize = 20; //每頁資料條數String sortString = "age.asc,gender.desc";//如果你想排序的話逗號分隔可以排序多列PageBounds pageBounds = newPageBounds(page, pageSize , Order.formString(sortString));List list = findByCity("BeiJing",pageBounds);//獲得結果集條總數PageList pageList = (PageList)list;System.out.println("totalCount: "+ pageList.getPaginator().getTotalCount());

 

PageList類是繼承於ArrayList的,這樣Dao中就不用為了專門分頁再多寫一個方法。

使用PageBounds這個對象來控制結果的輸出,常用的使用方式一般都可以通過建構函式來配置。

new PageBounds();//預設建構函式不提供分頁,返回ArrayListnew PageBounds(int limit);//取TOPN操作,返回ArrayListnew PageBounds(Order... order);//只排序不分頁,返回ArrayListnew PageBounds(int page, int limit);//預設分頁,返回PageListnew PageBounds(int page, int limit, Order... order);//分頁加排序,返回PageListnew PageBounds(int page, int limit, List<Order> orders,boolean containsTotalCount);//使用containsTotalCount來決定查不查詢totalCount,即返回ArrayList還是PageList


 

=========================================

如果用的是Spring MVC的話可以把JSON的配置寫成這樣:

<mvc:annotation-driven>    <mvc:message-converters register-defaults="true">        <bean class="org.springframework.http.converter.StringHttpMessageConverter">            <constructor-argvalue="UTF-8"/>                </bean>         <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">             <property name="objectMapper">                 <bean class="com.github.miemiedev.mybatis.paginator.jackson2.PageListJsonMapper"/>             </property>         </bean>     </mvc:message-converters> </mvc:annotation-driven>

那麼在Controller就可以這樣用了:

@ResponseBody@RequestMapping(value ="/findByCity.json")public List findByCity(@RequestParam String city,                 @RequestParam(required =false,defaultValue ="1") intpage,                 @RequestParam(required =false,defaultValue ="30") intlimit,                 @RequestParam(required =false) String sort,                 @RequestParam(required =false) String dir) {     return userService.findByCity(city, newPageBounds(page, limit, Order.create(sort,dir)));} 
 


然後序列化後的JSON字串就會變成這樣的:

{    "items":[        {"NAME":"xiaoma","AGE":30,"GENDER":1,"ID":3,"CITY":"BeiJing"},        {"NAME":"xiaoli","AGE":30,"SCORE":85,"GENDER":1,"ID":1,"CITY":"BeiJing"},        {"NAME":"xiaowang","AGE":30,"SCORE":92,"GENDER":0,"ID":2,"CITY":"BeiJing"},        {"NAME":"xiaoshao","AGE":30,"SCORE":99,"GENDER":0,"ID":4,"CITY":"BeiJing"}    ],    "slider": [1, 2, 3, 4, 5, 6, 7],    "hasPrePage":false,    "startRow": 1,    "offset": 0,    "lastPage":false,    "prePage": 1,    "hasNextPage":true,    "nextPage": 2,    "endRow": 30,    "totalCount": 40351,    "firstPage":true,    "totalPages": 1346,    "limit": 30,    "page": 1}

 

=========================================

在SpringMVC中使用JSTL的話可以參考一下步驟(懶人用法)

在Spring設定檔中加入攔截器,或則參考攔截器實現定義自己的攔截器

<mvc:interceptors>    <mvc:interceptor>        <mvc:mapping path="/**"/>        <bean class="com.github.miemiedev.mybatis.paginator.springmvc.PageListAttrHandlerInterceptor"/>    </mvc:interceptor></mvc:interceptors>

 

然後Controller方法可以這樣寫

@RequestMapping(value ="/userView.action")public ModelAndView userView(@RequestParam String city,                 @RequestParam(required =false,defaultValue ="1")intpage,                 @RequestParam(required =false,defaultValue ="30")intlimit,                 @RequestParam(required =false) String sort,                 @RequestParam(required =false) String dir) {    List users = userService.findByCity(city,newPageBounds(page, limit, Order.create(sort,dir)));    returnnewModelAndView("account/user","users", users);}

 

JSP中就可以這樣用了,攔截器會將PageList分拆添加Paginator屬性,預設命名規則為"原屬性名稱"+"Paginator"

<table>    <c:forEach items="${users}"var="user">        <tr>            <td>${user['ID']}</td>            <td>${user['NAME']}</td>            <td>${user['AGE']}</td>        </tr>    </c:forEach></table>上一頁: ${usersPaginator.prePage} 當前頁: ${usersPaginator.page} 下一頁: ${usersPaginator.nextPage} 總頁數: ${usersPaginator.totalPages} 總條數: ${usersPaginator.totalCount} 更多屬性參考Paginator類提供的方法

 

=========================================

如果用如下方法設定pageBounds,當前這個查詢就可以用兩個線程同時查詢list和totalCount了

pageBounds.setAsyncTotalCount(true);

如果所有的分頁查詢都是用非同步方式查詢list和totalCount,可以在外掛程式配置加入asyncTotalCount屬性

<plugin interceptor="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor">    <property name="dialectClass" value="com.github.miemiedev.mybatis.paginator.dialect.OracleDialect"/>    <property name="asyncTotalCount" value="true"/></plugin>

但是你仍然可以用下面代碼強制讓這個查詢不用非同步

pageBounds.setAsyncTotalCount(false);

 

當然需要注意的是,只要你用到了非同步查詢,由於裡面使用了線程池,所以在使用時就要加入清理監聽器,以便在停止服務時關閉線程池。需要在web.xml中加入

<listener>    <listener-class>com.github.miemiedev.mybatis.paginator.CleanupMybatisPaginatorListener</listener-class></listener>

 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.