几种常见mybatis分页实现[通俗易懂]

几种常见mybatis分页实现[通俗易懂]mybatis框架分页实现,有几种方式,最简单的就是利用原生的sql关键字limit来实现,还有一种就是利用interceptor来拼接sql,实现和limit一样的功能,再一个就是利用PageHelper来实现。这里讲解这三种常见的实现方式:无论哪种实现方式,我们返回的结果,不能再使用List了,需要一个自定义对象Pager。packagecom.xxx.mybatis.bean;…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

mybatis框架分页实现,有几种方式,最简单的就是利用原生的sql关键字limit来实现,还有一种就是利用interceptor来拼接sql,实现和limit一样的功能,再一个就是利用PageHelper来实现。这里讲解这三种常见的实现方式:

无论哪种实现方式,我们返回的结果,不能再使用List了,需要一个自定义对象Pager。

package com.xxx.mybatis.bean;
import java.util.List;
public class Pager<T> {
	private int page;//分页起始页
	private int size;//每页记录数
	private List<T> rows;//返回的记录集合
	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<T> getRows() {
		return rows;
	}
	public void setRows(List<T> rows) {
		this.rows = rows;
	}
	public long getTotal() {
		return total;
	}
	public void setTotal(long total) {
		this.total = total;
	}
}

limit关键字实现:

UserDao.java增加两个方法

public List<User> findByPager(Map<String, Object> params);
public long count();

UserMapper.xml中增加两个查询

<select id="findByPager" resultType="com.xxx.mybatis.domain.User">
	select * from xx_user limit #{page},#{size}
</select>
<select id="count" resultType="long">
	select count(1) from xx_user
</select>

 UserService.java中增加分页方法

public Pager<User> findByPager(int page,int size){
	Map<String, Object> params = new HashMap<String, Object>();
	params.put("page", (page-1)*size);
	params.put("size", size);
	Pager<User> pager = new Pager<User>();
	List<User> list = userDao.findByPager(params);
	pager.setRows(list);
	pager.setTotal(userDao.count());
	return pager;
}

这是最直观的实现方式,也是最简单的,不用任何插件或者工具就能够很方便的实现的方法。 

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")
	@Override
	public 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");
			Map<String, Object> params = (Map<String, Object>)parameterHandler.getParameterObject();
			page = (int)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();
	}

	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties properties) {
		String limit = properties.getProperty("limit","10");
		this.page = Integer.parseInt(limit);
		this.dbType = properties.getProperty("dbType", "mysql");
	}

}

我们之前在service的findByPager方法里面,为了给limit传入两个参数,其中page做了计算,这里使用拦截器的方式就无需计算了:

几种常见mybatis分页实现[通俗易懂]

public Pager<User> findByPager(int page,int size){
	Map<String, Object> params = new HashMap<String, Object>();
	params.put("page", page);
	params.put("size", size);
	Pager<User> pager = new Pager<User>();
	List<User> list = userDao.findByPager(params);
	pager.setRows(list);
	pager.setTotal(userDao.count());
	return pager;
}

spring配置中,增加plugin设置:

几种常见mybatis分页实现[通俗易懂]

到这里,你也许也猜到了MyPageInterceptor实际上是以一种拦截器的方式在程序执行findByPager方法的时候,对语句会增加limit page,size的拼接,还是和第一种原生实现思路一样,所以这里需要对UserMapper.xml配置文件中的findByPager这个查询对应的语句中的limit #{page},#{size}这部分去掉,变为如下的样子:

几种常见mybatis分页实现[通俗易懂]

至此,通过拦截器插件的方式也实现了分页功能了。 

PageHelper实现:

这种方式实现需要我们引入maven依赖。

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

spring.xml配置文件做一下修改:

 <bean id="pageInterceptor" class="com.github.pagehelper.PageHelper">
	<property name="properties">
		<props>
			<prop key="helperDialect">mysql</prop>
			<prop key="reasonable">true</prop>
			<prop key="supportMethodsArguments">true</prop>
			<prop key="params">count=countSql</prop>
		</props>
	</property>
 </bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource" />
	<property name="mapperLocations"  value="classpath:com/xxx/mybatis/dao/*Mapper.xml"/>
	<property name="plugins" ref="pageInterceptor"></property>
</bean> 

service层的方法,做一些修改:

public Pager<User> findByPager(int page,int size){
	Pager<User> pager = new Pager<User>();
	Page<User> res = PageHelper.startPage(page,size);
	userDao.findAll();
	pager.setRows(res.getResult());
	pager.setTotal(res.getTotal());
	return pager;
}

至此,PageHelper工具方法实现分页也实现了。其实PageHelper方法也是第二种使用Interceptor拦截器方式的一种三方实现,它内部帮助我们实现了Interceptor的功能。所以我们不用自定义MyPageInterceptor这个类了。实际上也是在运行查询方法的时候,进行拦截,然后设置分页参数。所以PageHelper.startPage(page,size)这一句需要显示调用,然后再执行userDao.findAll(),在查询所有用户信息的时候,会进行一个分页参数设置,让放回的结果只是分页的结果,而不是全部集合。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180010.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Git常用指令[通俗易懂]

    Git常用指令[通俗易懂]####gitclone远端地址 克隆到本地####gitpulloriginmaster 更新到本地####gitadd.####gitcommit-m"xxx"####gitpushoriginmaster 提交代码####gitbranch分支名称 创建分支####gitcheckout分支名 切换分支####gitbranch-D分支名; 彻底删除分…

  • 防火墙透明模式和路由模式区别_防火墙的部署模式

    防火墙透明模式和路由模式区别_防火墙的部署模式防火墙能够工作在三种模式下:路由模式、透明模式、混合模式。如果防火墙以第三层对外连接(接口具有IP地址),则认为防火墙工作在路由模式下;若防火墙通过第二层对外连接(接口无IP地址),则防火墙工作在透明模式下;若防火墙同时具有工作在路由模式和透明模式的接口(某些接口具有IP地址,某些接口无IP地址),则防火墙工作在混合模式下。防火墙三种工作模式的简介1、路由模式当防火墙位于内部网络和外部网络之间时,需要将防火墙与内部网络、外部网络以及DMZ三个区域相连的接口分别配置成不同网段的IP地址

    2022年10月23日
  • OpenResty 最佳实践学习–实战演习笔记(5)

    本篇整理openresty的子查询和执行阶段!子查询 capture a —> b 子查询 ,查询内部对另外一个location做了一次查询,并返回结果!调用另一个location不发htttp,相当于内部调用了一次c函数! 京东商品详情页 –openresty的capture (1)很多api (2)无法降级服务 最好只有一个API接口! 每个loca

  • 关于visual profiler 的“The application being profiled returnd a non-zero return code“解决方法

    关于visual profiler 的“The application being profiled returnd a non-zero return code“解决方法这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好!这是你第一次使用Markdown编辑器所展示的欢迎页。如果你想学习如何使用Mar

  • linux设置定时关机命令,linux定时关机命令是什么?

    linux设置定时关机命令,linux定时关机命令是什么?linux定时关机命令是什么?在之前的教程中,我们分享了win7系统定时关机命令的使用方法,给网友们带来了不少的便利。也有网友使用的是Linux系统,因此,他们好奇:Linux系统的定时关机命令跟win7系统的一样吗?Linux系统定时关机的命令是什么?在今天的教程中,我们就简单了解一下同样的功能在linux下使用shutdown命令和在Windows下使用shutdown命令的不同。系统关机1….

  • 明翰英语教学系列之雅思常见词汇与固定搭配篇V1.0(持续更新)「建议收藏」

    明翰英语教学系列之雅思常见词汇与固定搭配篇V1.0(持续更新)「建议收藏」按场景记忆是最高效的,这里给出的音标全部是英氏。跟你没有相关性的表达你也要记下来,不仅可以用在听力、阅读、写作,还因为在雅思口语PART3中可能会问一些分类讨论的话题,不仅仅只说自己的情况。

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号