美文网首页Tool数据框架Mybatis
Mybatis分页插件mybatis-paginator

Mybatis分页插件mybatis-paginator

作者: 尽心上 | 来源:发表于2016-06-29 16:54 被阅读1904次

    插件地址https://github.com/miemiedev/mybatis-paginator

    在Maven中加入依赖:

    <dependency>
        <groupId>com.github.miemiedev</groupId>
        <artifactId>mybatis-paginator</artifactId>
        <version>1.2.17</version>
    </dependency>
    
    Mybatis 配置文件添加分页插件:

    <property name="plugins">
         <list>
            <bean class="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor">                                                                                              
               <property name="dialectClass" value="com.github.miemiedev.mybatis.paginator.dialect.MySQLDialect"></property>
            </bean>
         </list>
    </property> 
    
    创建一个查询,内容可以是任何Mybatis表达式,包括foreach和if等:
    <select id="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);
    
        return getSqlSession().selectList("db.table.user.findByCity", params, pageBounds);
    }
    
    调用方式(分页加多列排序):

    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中就不用为了专门分页再多写一个方法。
    使用PageBounds这个对象来控制结果的输出,常用的使用方式一般都可以通过构造函数来配置。

    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
    
    如果用的是Spring MVC的话可以把JSON的配置写成这样:

    <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>
    

    源地址 Mybatis分页和Spring的集成

    相关文章

      网友评论

        本文标题:Mybatis分页插件mybatis-paginator

        本文链接:https://www.haomeiwen.com/subject/zzrxjttx.html