寫了一個Mybatis分頁控件,在這記錄一下使用方式。html
在Maven中加入依賴:java
<dependencies> ... <dependency> <groupId>com.github.miemiedev</groupId> <artifactId>mybatis-paginator</artifactId> <version>1.2.17</version> </dependency> ... </dependencies>
Mybatis配置文件添加分頁插件: git
<?xml version="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"> <property name="dialectClass" value="com.github.miemiedev.mybatis.paginator.dialect.OracleDialect"/> </plugin> </plugins> </configuration>
建立一個查詢,內容能夠是任何Mybatis表達式,包括foreach和if等: github
<select id="findByCity" resultType="map"> select * from TEST_USER where city = #{city}; </select>
Dao中的方法或許是這樣(用接口也是相似): web
public List findByCity(String city, PageBounds pageBounds){ Map<String, Object> params = new HashMap<String, Object>(); params.put("city",city); return getSqlSession().selectList("db.table.user.findByCity", params, pageBounds); }
調用方式(分頁加多列排序): spring
int page = 1; //頁號 int pageSize = 20; //每頁數據條數 String sortString = "age.asc,gender.desc";//若是你想排序的話逗號分隔能夠排序多列 PageBounds pageBounds = new PageBounds(page, pageSize , Order.formString(sortString)); List list = findByCity("BeiJing",pageBounds); //得到結果集條總數 PageList pageList = (PageList)list; System.out.println("totalCount: " + pageList.getPaginator().getTotalCount());
PageList類是繼承於ArrayList的,這樣Dao中就不用爲了專門分頁再多寫一個方法。
apache
使用PageBounds這個對象來控制結果的輸出,經常使用的使用方式通常均可以經過構造函數來配置。
json
new PageBounds();//默認構造函數不提供分頁,返回ArrayList new PageBounds(int limit);//取TOPN操做,返回ArrayList new PageBounds(Order... order);//只排序不分頁,返回ArrayList new PageBounds(int page, int limit);//默認分頁,返回PageList new PageBounds(int page, int limit, Order... order);//分頁加排序,返回PageList new PageBounds(int page, int limit, List<Order> orders, boolean containsTotalCount);//使用containsTotalCount來決定查不查詢totalCount,即返回ArrayList仍是PageList
========================================= mybatis
若是用的是Spring MVC的話能夠把JSON的配置寫成這樣: mvc
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="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") int page, @RequestParam(required = false,defaultValue = "30") int limit, @RequestParam(required = false) String sort, @RequestParam(required = false) String dir) { return userService.findByCity(city, new PageBounds(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") int page, @RequestParam(required = false,defaultValue = "30") int limit, @RequestParam(required = false) String sort, @RequestParam(required = false) String dir) { List users = userService.findByCity(city, new PageBounds(page, limit, Order.create(sort,dir))); return new ModelAndView("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>
完。