Mybatis 可以使用自定义插件,本文论述 Mybatis 的开源分页插件 pageHelper 的配置和使用
环境配置
- 配置 Maven 依赖
<!-- mybatis 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.0.0</version>
</dependency>
- 配置 分页插件
可以直接在 Mybatis 的配置文件中进行配置,也可以将 Mybatis 的插件配置托管到 Spring 。
- 在 Mybatis 中配置分页插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="helperDialect" value="mysql"/>
</plugin>
</plugins>
- 在 Spring 中配置分页插件(为便于理解位置,增加冗余代码)
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
scope="singleton">
<!-- 数据库连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 加载mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config-Spring.xml" />
<!-- mybatis 分页插件 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
helperDialect=mysql
reasonable=false
supportMethodsArguments=true
params=count=countSql
autoRuntimeDialect=true
</value>
</property>
</bean>
</array>
</property>
</bean>
- 分页插件中各属性的含义
属性 | 含义 | 默认值 | 可选值 |
---|---|---|---|
helperDialect | 数据库类型 | 自动检测 , (使用 SqlServer2012 数据库时, 需要手动指定为 sqlserver2012) | oracle,mysql,mariadb,sqlite, hsqldb,postgresql,db2, sqlserver,informix, h2,sqlserver2012, derby |
reasonable | 分页参数和结果合理化,为true时, 当查询页序数小于1自动搜索第一页数据, 当查询页序数大于数据总页数, 自动查询最后一页数据 | false | true/false |
params | 用于支持startPage(Object params)方法 | pageNum=pageNum; pageSize=pageSize; count=countSql; reasonable=reasonable; pageSizeZero=pageSizeZero | pageNum, pageSize, count, pageSizeZero, reasonable |
supportMethodsArguments | 为true时,分页插件会从查询方法的参数值中, 自动根据上面 params 配置的字段中取值, 查找到合适的值时就会自动分页 | false | true/false |
autoRuntimeDialect | 为 true 时,允许在运行时根据多数据源 自动识别对应方言的分页 | false, (使用 SqlServer2012 数据库时, 需要手动指定为 sqlserver2012) | true/false |
代码调用
- 一个仅仅关注条件而不关注搜索总条数的Dao层方法
<select id="getList" resultType="com.bestcxx.stu.springmybatis.model.TestTableOne">
SELECT
<include refid="Base_Column_List" />
FROM TEST_TABLE_ONE
</select>
-
调用方式分为两种
- 第一种:直接使用 插件的结果集合
@Autowired private TestTableOneMapper testTableOneMapper; @Override public Map<String,Object> getList() { Map<String,Object> map=new HashMap<String,Object>(); int pageNum=10;//查询页序数 int pageSize=2;//每页数据条数 //第一种,使用插件提供的结果形式,会有较多的冗余字段 //{"pageNum":-1,"pageSize":2,"size":2,"startRow":1,"endRow":2, //"total":6,"pages":3,"list":[{"id":1,"comment":"11"},{"id":2,"comment":"22"}], //"prePage":0,"nextPage":0,"isFirstPage":false,"isLastPage":false, //"hasPreviousPage":false,"hasNextPage":true,"navigatePages":8, //"navigatepageNums":[1,2,3],"navigateFirstPage":1,"navigateLastPage":3, //"firstPage":1,"lastPage":3} PageHelper.startPage(pageNum, pageSize);//第一行 List<TestTableOne> list=testTableOneMapper.getList();//第二行,本行代码必须紧跟第一行之后 PageInfo<TestTableOne> pageInfo=new PageInfo<TestTableOne>(list);//插件自带封装结果 map.put("pageInfo", pageInfo); return map; }
- 第二种:对分页结果进行二次处理
@Autowired
private TestTableOneMapper testTableOneMapper;
@Override
public Map<String,Object> getList() {
Map<String,Object> map=new HashMap<String,Object>();
int pageNum=10;//查询页序数
int pageSize=2;//每页数据条数
//第一种,使用插件提供的结果形式,会有较多的冗余字段
//第二种,自己对结果集合进行再次封装,这里可以采用上面的方法重写一个 PageInfo,这里便于理解单独取值
//{"pageInfo":{"当前页序数":3,"总页数":3,"每页数据大小":2,
//"list":[{"id":5,"comment":"55"},{"id":6,"comment":"66"}],"数据总数":6}}
Page<TestTableOne> page=PageHelper.startPage(pageNum, pageSize);//第一行
testTableOneMapper.getList();//第二行,本行代码必须紧跟第一行之后
//二次处理查询结果
Map<String,Object> map2=new HashMap<String,Object>();
map2.put("数据总数", page.getTotal());
map2.put("每页数据大小", page.getPageSize());
map2.put("当前页序数", page.getPageNum());
map2.put("总页数", page.getPages());
map2.put("list", page.getResult());
map.put("pageInfo", map2);
return map;
}
为什么分页失效了?
调用分页查询的时候,务必按照下面的顺序调用,并且,中间不允许有其他代码逻辑。
第一: PageHelper.startPage(pageNum, pageSize);
第二:集合搜索语句。
原因是 pagehelper 分页插件使用的策略是在 查询结果执行前增加了一些操作,在查询结束后释放,具体内容本文不做详述,有兴趣的读者可以继续探索一下。