电光石火-穿越时空电光石火-穿越时空


MyBatis分页插件PageHelper的使用

20160821224428078.jpg

从图中可以看出,mybatis中首先要在配置文件中配置一些东西,然后根据这些配置去创建一个会话工厂,再根据会话工厂创建会话,会话发出操作数据库的sql语句,然后通过执行器操作数据,再使用mappedStatement对数据进行封装,这就是整个mybatis框架的执行情况。那么mybatis的插件作用在哪一环节呢?它主要作用在Executor执行器与mappedeStatement之间,也就是说mybatis可以在插件中获得要执行的sql语句,在sql语句中添加limit语句,然后再去对sql进行封装,从而可以实现分页处理。 
搞清楚了分页插件的执行情况,下面来总结下mybatis中PageHelper的使用。

1. 需要引入PageHelper的jar包
如果没有使用maven,那直接把jar包导入到lib文件夹下即可,这个PageHelper插件在github上有开源,地址为:https://github.com/pagehelper/Mybatis-PageHelper/tree/master/src/main/java/com/github/pagehelper。 
如果使用了maven,那么只要在pom.xml中引入该插件即可,引入如下:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>4.1.4</version>
</dependency>

2. 在mybatis的全局配置文件mybatisConfig.xml中配置该插件

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
	    <!-- 日志开启 -->
        <setting name="logImpl" value="LOG4J"/>
		<!-- 全局映射器启用缓存 -->
		<setting name="cacheEnabled" value="true" />
		<!-- 查询时,关闭关联对象即时加载以提高性能 -->
		<setting name="lazyLoadingEnabled" value="true" />
		<!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
		<setting name="aggressiveLazyLoading" value="false" />
		<!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
		<setting name="multipleResultSetsEnabled" value="true" />
		<!-- 允许使用列标签代替列名 -->
		<setting name="useColumnLabel" value="true" />
		<!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
		<setting name="useGeneratedKeys" value="true" />
		<!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->
		<setting name="autoMappingBehavior" value="FULL" />
		<!-- 对于批量更新操作缓存SQL以提高性能 -->
		<setting name="defaultExecutorType" value="BATCH" />
		<!-- 数据库超过25000秒仍未响应则超时 -->
		<setting name="defaultStatementTimeout" value="25000" />
	</settings>
	
	<plugins>
		<!-- com.github.pagehelper为PageHelper类所在包名 -->
		<plugin interceptor="com.github.pagehelper.PageHelper">
			<!-- 4.0.0以后版本可以不设置该参数 -->
			<property name="dialect" value="mysql"/>
			<!-- 该参数默认为false -->
			<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
			<!-- 和startPage中的pageNum效果一样-->
			<property name="offsetAsPageNum" value="true"/>
			<!-- 该参数默认为false -->
			<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
			<property name="rowBoundsWithCount" value="true"/>
			<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
			<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
			<property name="pageSizeZero" value="true"/>
			<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
			<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
			<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
			<property name="reasonable" value="false"/>
			<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
			<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
			<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
			<!-- 不理解该含义的前提下,不要随便复制该配置 -->
			<property name="params" value="pageNum=pageHelperStart;pageSize=pageHelperRows;"/>
			<!-- 支持通过Mapper接口参数来传递分页参数 -->
			<property name="supportMethodsArguments" value="false"/>
			<!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
			<property name="returnPageInfo" value="none"/>
		</plugin>
	</plugins>
	
</configuration>  

3. 在执行sql前添加插件,完成分页功能
在查询的sql语句执行之前,添加一行代码PageHelper.startPage(1, 10);第一个参数表示第几页,第二个参数表示每页显示的记录数。这样在执行sql后就会将记录按照语句中设置的那样进行分页。如果需要获取总记录数的话,需要PageInfo类的对象,这个对象可以获取总记录数,下面看下测试的代码。

public class TestPageHelper {

    @Test
    public List getAnswerInfoDataTable(DataTableDto dataTableDto, Integer classId) throws Exception {
		String s=dataTableDto.getSearch();
		Integer page = 0;
		if(dataTableDto.length!=-1) {
			dataTableDto.start = dataTableDto.start == null ? 1 : dataTableDto.start;
			dataTableDto.length = dataTableDto.length == null ? 10 : dataTableDto.length;
			page = (dataTableDto.start / dataTableDto.length) + 1; //第几页
			PageHelper.startPage(page, dataTableDto.length);
		}
		List list=null;
		if(s==""){
			list=this.classAnswerDao.getAnswerDataTable(classId);
		}
		else{
			list=this.classAnswerDao.getAnswerDataTable2(s,classId);
		}
		return list;
	}
}


     可以看到,只显示出了10条数据,但是我总共有3096条数据,如果将参数改成(2,10),那么就会显示第二页不同的10条数据,在这就不测试了。这说明PageHelper插件可以帮助我们实现分页功能,例如EasyUI中就会传到后台分页参数信息,后台就可以根据参数获取分页数据等等。 
正如前面所说,这个PageHelper其实也有缺点,因为它对逆向工程生成的代码支持不好,不能对有查询条件的查询分页,会抛异常,上面是无条件查询的。当然,我们自己可以修改这个PageHelper插件,使其支持条件查询,当然,我是修改不了的……网上有修改过后的PageHelper插件,可以支持条件查询,相对来说就比较强大了,可以在自己的工程中依赖修改过后的分页插件进行开发。

本博客所有文章如无特别注明均为原创。作者:似水的流年
版权所有:《电光石火-穿越时空》 => MyBatis分页插件PageHelper的使用
本文地址:http://www.ilkhome.cn/index.php/archives/338/
欢迎转载!复制或转载请以超链接形式注明,文章为 似水的流年 原创,并注明原文地址 MyBatis分页插件PageHelper的使用,谢谢。

评论