文档章节

Mybatis分页和Spring的集成

miemiedev
 miemiedev
发布于 2013/06/04 14:25
字数 1001
阅读 48656
收藏 115

写了一个Mybatis分页控件,在这记录一下使用方式。

在Maven中加入依赖:

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


Mybatis配置文件添加分页插件:

<?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等:

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


完。

© 著作权归作者所有

共有 人打赏支持
miemiedev

miemiedev

粉丝 71
博文 2
码字总数 1543
作品 2
济南
程序员
加载中

评论(108)

杨万
杨万
你好楼主,我想用于sql server可以么?
xiaoluobotou
xiaoluobotou
看着很牛叉,
i
itxx2016
推荐国内最流行的iBatis、MyBatis代码生成网站: fwjava.com
网站在线生成,操作极其简单,生成的代码十分规范好用,经历过实战的主流代码啊.
现在,大多数知名的互联网公司都在用它.
l
lantian123
单表查询正常,我想求教多表关联查询方法。
比如运行SQL join 语句会出现12条数据,resultMap去重复数据后,只有2条数据。 问题是页面正常输出2个,但是总条数还是显示SQL的12个。 mybatis-paginator插件用什么办法让getTotalCount输出去掉重复数据后的总条数,也就是2条呢?
丿
丿随心丶秀爵
getSqlSession().selectList("db.table.user.findByCity", params, pageBounds);
请问你这个只针对手动获取session来做查询的方式吗?
session昂spring托管的方式有实现吗?
ok_
ok_
如果多数据源情况下,怎么配置呢,mysql和Oracle一起
阿丢丢
阿丢丢
为何内容写的都是 MySQL的 但是 配置的时候用的是 OracleDialect.... 哎呀呀呀
m
mascothaojun
支持sqlserver2008吗?在源码没看到有这个类
牛牛客
PageBounds pageBounds = new PageBounds(page, pageSize , Order.formString("id.asc"),true);
  
  Map<String,Object> map = new HashMap<String,Object>();
    if(activityName!=null && activityName!=""){
      map.put("activityName", activityName);
    }
  
    PageList lists = bljBannersFacade.getListByPage(map, pageBounds);
    view.addAttribute("lists", lists);
    System.err.println(lists.getPaginator().getPage()+"------"+lists.getPaginator().getPrePage()+"--------"+lists.getPaginator().getTotalPages());
    你好,分页数据是正确的,但是分页信息为null
后zhi后jue
你好,我用的是sqlserver2005的dialect,但是分页的结果不对,如:第三页里面的第一条数据就是第二页里面的最后一条数据。数据重复了。不知道是不是插件的bug。我用mysql就没问题
Spring Boot MyBatis 连接数据库

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/catoop/article/details/50553714 最近比较忙,没来得及抽时间把MyBatis的集成发出来,其实mybatis官网在201...

单红宇
2016/01/21
0
0
pagehelper/Mybatis-PageHelper

Mybatis分页插件 - PageHelper 如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件。 分页插件支持任何复杂的单表、多表分页,部分特殊情况请看重要提示。 想要使用分页...

java梦想家01
2015/08/03
0
0
Spring Boot [集成-MyBatis]

导读: 在上篇文章中我们介绍了spring-data-jpa的一些常用方法,在这篇文章中我们在介绍关于mybatis与Spring Boot 的集成,及一些常用方法 集成: 这里有两种方式,一种是常规的Spring 应用的...

yangrd
08/27
0
0
shenzhanwang/SSM

SSM SpringMVC,Mybatis,Spring三大框架的整合总是很麻烦,在此提供一个已经整合好三大框架的包,可以直接下载导入Myeclipse使用,项目基于Maven做依赖管理。项目基于Mysql自带的Sakila数据库...

shenzhanwang
2016/11/16
0
0
深入浅出MyBatis-快速入门

深入浅出MyBatis-快速入门 深入浅出MyBatis-Configuration 深入浅出MyBatis-MapperBuilder 深入浅出MyBatis-Sqlsession 深入浅出Mybatis-插件原理 深入浅出Mybatis-分页 深入浅出Mybatis-sql...

perfectspr
2014/11/26
0
1

没有更多内容

加载失败,请刷新页面

加载更多

Django支持中文

django是支持中文界面, 先找到Django语言包安装目录,我的在: /usr/local/python3/lib/python3.6/site-packages/django/conf/locale 有zh-Hans和zh-Hant两个文件, 其中zh-Hans是简体中文,...

MichaelShu
18分钟前
1
0
迷宫问题:顺序栈解法

采用顺序栈以及回溯法,一个比较简单的问题,但是从来没有写过,也算是弥补一下自己欠数据结构的债吧,居然也花了一个半小时,无地自容了。。 定义好数据结构求解算法就显得容易一些了。 st...

LoSingSang
24分钟前
0
0
Zookeeper 概述及应用场景

一、概述 分布式协调技术,主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成"脏数据"的后果。 ZooKeeper是一个分布式的,开放源码的分布式应用...

PeakFang-BOK
32分钟前
0
0
(译)OpenGL ES2.0 – Iphone开发指引

教程截图: OpenGL ES 是可以在iphone上实现2D和3D图形编程的低级API。 如果你之前接触过 cocos2d,sparrow,corona,unity 这些框架,你会发现其实它们都是基于OpenGL上创建的。 多数程序员...

robslove
42分钟前
0
0
金九银十跳槽季,程序员面试点解析之Java专场

前言 近年来Java工程师这个岗位炙手可热,市场需求大,学习Java的人也越来越多,所以IT企业与求职者的选择都比较多,那么IT企业在面试时都会提哪些问题呢。下面为大家分享 Java高级工程师面试...

老道士
44分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部