Mybatis分页插件PageHelper的配置和简单使用方法(推荐)
前言
在web开发过程中涉及到表格时,例如dataTable,就会产生分页的需求,通常我们将分页方式分为两种:前端分页和后端分页。
前端分页
一次性请求数据表格中的所有记录(ajax),然后在前端缓存并且计算count和分页逻辑,一般前端组件(例如dataTable)会提供分页动作。
特点是:简单,很适合小规模的web平台;当数据量大的时候会产生性能问题,在查询和网络传输的时间会很长。
后端分页
在ajax请求中指定页码(pageNum)和每页的大小(pageSize),后端查询出当页的数据返回,前端只负责渲染。
特点是:复杂一些;性能瓶颈在MySQL的查询性能,这个当然可以调优解决。一般来说,web开发使用的是这种方式。
我们说的也是后端分页。
MySQL对分页的支持
简单来说MySQL对分页的支持是通过limit子句。请看下面的例子。
limit关键字的用法是
LIMIT[offset,]rows
offset是相对于首行的偏移量(首行是0),rows是返回条数。
#每页10条记录,取第一页,返回的是前10条记录 select*fromtableAlimit0,10; #每页10条记录,取第二页,返回的是第11条记录,到第20条记录, select*fromtableAlimit10,10;
这里提一嘴的是,MySQL在处理分页的时候是这样的:
limit1000,10-过滤出1010条数据,然后丢弃前1000条,保留10条。当偏移量大的时候,性能会有所下降。
limit100000,10-会过滤10w+10条数据,然后丢弃前10w条。如果在分页中发现了性能问题,可以根据这个思路调优。
Mybatis分页插件PageHelper
在使用JavaSpring开发的时候,Mybatis算是对数据库操作的利器了。不过在处理分页的时候,Mybatis并没有什么特别的方法,一般需要自己去写limit子句实现,成本较高。好在有个PageHelper插件。
1、POM依赖
Mybatis的配置就不多提了。PageHelper的依赖如下。需要新的版本可以去maven上自行选择
com.github.pagehelper pagehelper 4.1.4
2、Mybatis对PageHelper的配置
打开Mybatis配置文件,一般在Resource路径下。我这里叫mybatis-config.xml。
这里要注意的是PageHelper相关的配置。
如果你没有加载Mybatis配置文件,那么使用的是Mybatis默认的配置。如何加载Mybatis配置文件呢?
到你的dataSrouce配置中。
在配置sqlSessionFactory的时候,指定Mybatis核心配置文件和mapper的路径,代码如下
@Bean(name="moonlightSqlSessionFactory") @Primary publicSqlSessionFactorymoonlightSqlSessionFactory(@Qualifier("moonlightData")DataSourcedataSource)throwsException{ SqlSessionFactoryBeanbean=newSqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(newPathMatchingResourcePatternResolver().getResources("classpath:mybatis-mapper/*.xml")); bean.setConfigLocation(newClassPathResource("mybatis-config.xml")); returnbean.getObject(); }
说明:
这里配置的mapper.xml存放路径,在Resource/mybatis-mapper文件夹下
这里配置的mybatis-config.xml文件,在Resource/下
3、分页
准备一个mapper.xml,测试就随便写一个吧,干脆就用工程里的一个。
这里这个查询,是一个典型的多条件查询,我们要做的是对多条件匹配到的记录进行分页。
id,name,type,`group`,geo,createTime,updateTime select fromgeoFencewhere1=1 andtype=#{type} andnamelikeconcat('%',#{name},'%') and`group`likeconcat('%',#{group},'%') andcreateTime>=#{startTime} andcreateTime<=#{endTime}
在Mapper.java接口中编写对应的方法
ListqueryGeoFence(GeoFenceQueryParamgeoFenceQueryParam);
先上分页代码,后面再说明
@RequestMapping(value="/fence/query",method=RequestMethod.POST) @ResponseBody publicResponsequeryFence(@RequestBodyGeoFenceQueryParamgeoFenceQueryParam){ try{ IntegerpageNum=geoFenceQueryParam.getPageNum()!=null?geoFenceQueryParam.getPageNum():1; IntegerpageSize=geoFenceQueryParam.getPageSize()!=null?geoFenceQueryParam.getPageSize():10; PageHelper.startPage(pageNum,pageSize); Listlist=moonlightMapper.queryGeoFence(geoFenceQueryParam); returnnewResponse(ResultCode.SUCCESS,"查询geoFence成功",list); }catch(Exceptione){ logger.error("查询geoFence失败",e); returnnewResponse(ResultCode.EXCEPTION,"查询geoFence失败",null); } }
说明:
1、PageHelper的优点是,分页和Mapper.xml完全解耦。实现方式是以插件的形式,对Mybatis执行的流程进行了强化,添加了总数count和limit查询。属于物理分页。
2、有一个安全性问题,需要注意一下,不然可能导致分页错乱。我这里直接粘贴了这篇博客里的一段话。
4.什么时候会导致不安全的分页?
PageHelper方法使用了静态的ThreadLocal参数,分页参数和线程是绑定的。
只要你可以保证在PageHelper方法调用后紧跟MyBatis查询方法,这就是安全的。因为PageHelper在finally代码段中自动清除了ThreadLocal存储的对象。
如果代码在进入Executor前发生异常,就会导致线程不可用,这属于人为的Bug(例如接口方法和XML中的不匹配,导致找不到MappedStatement时),这种情况由于线程不可用,也不会导致ThreadLocal参数被错误的使用。
但是如果你写出下面这样的代码,就是不安全的用法:
PageHelper.startPage(1,10); Listlist; if(param1!=null){ list=countryMapper.selectIf(param1); }else{ list=newArrayList (); }
这种情况下由于param1存在null的情况,就会导致PageHelper生产了一个分页参数,但是没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,就可能导致不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。
上面这个代码,应该写成下面这个样子:
Listlist; if(param1!=null){ PageHelper.startPage(1,10); list=countryMapper.selectIf(param1); }else{ list=newArrayList (); }
这种写法就能保证安全。
如果你对此不放心,你可以手动清理ThreadLocal存储的分页参数,可以像下面这样使用:
Listlist; if(param1!=null){ PageHelper.startPage(1,10); try{ list=countryMapper.selectAll(); }finally{ PageHelper.clearPage(); } }else{ list=newArrayList (); }
这么写很不好看,而且没有必要。
总结
以上所述是小编给大家介绍的Mybatis分页插件PageHelper的配置和简单使用方法(推荐),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!