MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
今天我们就来学学mybatis框架分页实现,有几种方式,最简单的就是利用原生的sql关键字limit来实现,还有一种就是利用interceptor来拼接sql,实现和limit一样的功能,再一个就是利用PageHelper来实现。这里讲解这三种常见的实现方式:
无论哪种实现方式,我们返回的结果,不能再使用List了,需要一个自定义对象Pager。
package com.xxx.mybatis.bean;import java.util.List;public class Pager {private int page;//分页起始页private int size;//每页记录数private List//返回的记录集合private long total;//总记录条数public int getPage() {return page;}public void setPage(int page) {this.page = page;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}public List{return rows;}public void setRows(List {this.rows = rows;}public long getTotal() {return total;}public void setTotal(long total) {this.total = total;}}
rows;
getRows()
rows)
limit关键字实现:
UserDao.java增加两个方法
public List;public long count();
findByPager(Map)
params
UserMapper.xml中增加两个查询
select * from xx_user limit #{page},#{size}select>select count(1) from xx_userselect>
UserService.java中增加分页方法
public Pager{Mapparams = new HashMapparams.put("page", (page-1)*size);params.put("size", size);Pagernew Pagerparams);pager.setRows(list);pager.setTotal(userDao.count());return pager;}
findByPager(int page,int size)
pager =
();List
list = userDao.findByPager(
这是最直观的实现方式,也是最简单的,不用任何插件或者工具就能够很方便的实现的方法。
interceptor plugin实现:
需要定义一个类实现Interceptor接口
MyPageInterceptor.java
package com.xxx.mybatis.bean;import java.sql.Connection;import java.util.Map;import java.util.Properties;import org.apache.ibatis.executor.parameter.ParameterHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Plugin;import org.apache.ibatis.plugin.Signature;import org.apache.ibatis.reflection.MetaObject;import org.apache.ibatis.reflection.SystemMetaObject;@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class,Integer.class})})public class MyPageInterceptor implements Interceptor {private int page;private int size;@SuppressWarnings("unused")private String dbType; @SuppressWarnings("unchecked")@Overridepublic Object intercept(Invocation invocation) throws Throwable {System.out.println("plugin is running...");StatementHandler statementHandler = (StatementHandler)invocation.getTarget();MetaObject metaObject = SystemMetaObject.forObject(statementHandler);while(metaObject.hasGetter("h")){Object object = metaObject.getValue("h");metaObject = SystemMetaObject.forObject(object);}while(metaObject.hasGetter("target")){Object object = metaObject.getValue("target");metaObject = SystemMetaObject.forObject(object);}MappedStatement mappedStatement = (MappedStatement)metaObject.getValue("delegate.mappedStatement");String mapId = mappedStatement.getId();if(mapId.matches(".+ByPager$")){ParameterHandler parameterHandler = (ParameterHandler)metaObject.getValue("delegate.parameterHandler");Mapint)params.get("page");size = (int)params.get("size");String sql = (String) metaObject.getValue("delegate.boundSql.sql");sql += " limit "+(page-1)*size +","+size;metaObject.setValue("delegate.boundSql.sql", sql);}return invocation.proceed();} @Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);} @Overridepublic void setProperties(Properties properties) {String limit = properties.getProperty("limit","10");this.page = Integer.parseInt(limit);this.dbType = properties.getProperty("dbType", "mysql");} }
params = (Map
)parameterHandler.getParameterObject();page = (
我们之前在service的findByPager方法里面,为了给limit传入两个参数,其中page做了计算,这里使用拦截器的方式就无需计算了:
public Pager{Mapparams = new HashMapparams.put("page", page);params.put("size", size);Pagernew Pagerparams);pager.setRows(list);pager.setTotal(userDao.count());return pager;}
findByPager(int page,int size)
pager =
();List
list = userDao.findByPager(
spring配置中,增加plugin设置:
到这里,你也许也猜到了MyPageInterceptor实际上是以一种拦截器的方式在程序执行findByPager方法的时候,对语句会增加limit page,size的拼接,还是和第一种原生实现思路一样,所以这里需要对UserMapper.xml配置文件中的findByPager这个查询对应的语句中的limit#{page},#{size}这部分去掉,变为如下的样子:
至此,通过拦截器插件的方式也实现了分页功能了。
PageHelper实现:
这种方式实现需要我们引入maven依赖。
com.github.pagehelpergroupId>pagehelperartifactId>4.2.1version> dependency>
spring.xml配置文件做一下修改:
mysqlprop>trueprop>trueprop>count=countSqlprop>props>property> bean> property>bean>
service层的方法,做一些修改:
public Pager{Pagernew Pagerreturn pager;}
findByPager(int page,int size)
pager =
();Page
res = PageHelper.startPage(page,size);userDao.findAll();pager.setRows(res.getResult());pager.setTotal(res.getTotal());
至此,PageHelper工具方法实现分页也实现了。其实PageHelper方法也是第二种使用Interceptor拦截器方式的一种三方实现,它内部帮助我们实现了Interceptor的功能。所以我们不用自定义MyPageInterceptor这个类了。实际上也是在运行查询方法的时候,进行拦截,然后设置分页参数。所以PageHelper.startPage(page,size)这一句需要显示调用,然后再执行userDao.findAll(),在查询所有用户信息的时候,会进行一个分页参数设置,让放回的结果只是分页的结果,而不是全部集合。
零基础学习Mybatis,推荐动力节点Mybatis菜鸟教程,通过本课程的学习,可以在最短的时间内学会使用持久层框架MyBatis,在该视频中没有废话,都是干货,该视频的讲解不是学术性研究,项目中用什么,这里就讲什么,如果您现在项目中马上要使用MyBatis框架,那么您只需要学习完此教程,就可以顺利的使用MyBatis开发了。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.