几种常见mybatis分页实现

2023-05-16

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做了计算,这里使用拦截器的方式就无需计算了:

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设置:

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

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

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(),在查询所有用户信息的时候,会进行一个分页参数设置,让放回的结果只是分页的结果,而不是全部集合。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

几种常见mybatis分页实现 的相关文章

  • 无人驾驶小车调试笔记(七)-- 相机校准

    简介 xff1a 在第五节的内容中 xff0c 我们学习了使用rqt工具集观看摄像头视频流的方法 xff0c 细心的同学应该会发现camera node发布的视频数据中的图像有变形现象 xff0c 图像变形会导致直线不直 xff0c 部分区
  • Python实现MySql、SqlServer增删改查操作

    span class token keyword import span pymssql span class token keyword def span span class token function connection sql
  • ds1302——斌哥51

    以下内容分别借鉴了 清翔 51 xff0c 斌哥51 xff0c 以及CSDN 普通的不普通少年 内部结构 xff1a DS1302 包括时钟 日历寄存器和 31 字节 xff08 8 位 xff09 的数据暂存寄存器 xff0c 数据通信
  • AD添加LOGO

    先上原文链接 xff1a http www allchiphome com circuit pcb logo creator http www allchiphome com circuit pcb logo creator http ww
  • 视频播放组件实战【LivePlayer H5播放器】

    在公司项目开发中 xff0c 有一个项目里面需要做一个视频播放的功能 xff0c 播放方式是调用海康平台提供的接口获取流地址来进行视频的播放并且最重要的是需要支持flash 由于前端用的Vue xff0c 对比了几个 xff0c 最后选择了
  • 如何用示波器测量串口

    如何确定时基 假如要测量的波特率为9600 则每一比特位的时间为 xff1a 1 9600 104 s xff0c 一般示波器横向上每个大格子里5个小格子 xff0c 要想看清一比特位一般需要一个小格子就够了 xff0c 则时基为 xff1
  • Keil使用命令行附加预定义宏编译

    1 前言 很多时候 xff0c 一份Keil工程代码可能需要满足多个不同的应用场景 可以通过逻辑判断 xff0c 将多个不同的点集成在一份代码之中 xff0c 但是嵌入式往往特别关注RAM空间 xff0c 集成过多的逻辑判断 xff0c R
  • Python的函数装饰器,@staticmethod、@classmethod 和 @property

    什么是Python 的 函数装饰器 xff1f Python 内置的 3 种函数装饰器 xff0c 分别是 xff20 staticmethod xff20 classmethod 和 64 property 那么 xff0c 函数装饰器的
  • C++11:原子交换函数compare_exchange_weak和compare_exchange_strong

    我们知道在C 43 43 11中引入了mutex和方便优雅的lock guard 但是有时候我们想要的是性能更高的无锁实现 xff0c 下面我们来讨论C 43 43 11中新增的原子操作类Atomic xff0c 我们可以利用它巧妙地实现无
  • C++11条件变量:notify_one()与notify_all()的区别

    notify one 与notify all 常用来唤醒阻塞的线程 notify one xff1a 因为只唤醒等待队列中的第一个线程 xff1b 不存在锁争用 xff0c 所以能够立即获得锁 其余的线程不会被唤醒 xff0c 需要等待再次
  • 数据库:group by 的使用

    一 概述 group by的意思是根据by对数据按照哪个字段进行分组 xff0c 或者是哪几个字段进行分组 二 语法 select 字段 from 表名 where 条件 group by 字段 或者 select 字段 from 表名 g
  • C++中 std::vector 的6种初始化方法

    1 vector lt int gt list1 默认初始化 xff0c 最常用 此时 xff0c vector为空 xff0c size为0 xff0c 表明容器中没有元素 xff0c 而且 capacity 也返回 0 xff0c 意味
  • MIMO雷达处理1

    参考文献 MIMO RADAR SIGNAL PROCESSING 以下为我自己的理解 xff0c 如有问题 xff0c 请指出 目录 初步分析虚拟阵列123 确认目标数 初步分析 MIMO radar与相控阵雷达区别在于MIMO中的各天线
  • AndroidStudio生成aar包和如何使用aar包

    我用的是android studio 2 0正式版 1 简介 aar包是Android studio下打包android工程中src res lib后生成的aar文件 xff0c aar包导入其他android studio 工程后 xff
  • C++智能指针详解:shared_ptr

    C 43 43 没有内存回收机制 xff0c 每次程序员new出来的对象需要手动delete xff0c 流程复杂时可能会漏掉delete xff0c 导致内存泄漏 于是C 43 43 引入智能指针 xff0c 可用于动态资源管理 xff0
  • C++算法题:关于树的算法

    问题1 xff1a 输入一棵二元查找树 xff0c 将该二元查找树转换成一个排序的双向链表 要求不能创建任何新的结点 xff0c 只调整指针的指向 什么是二元查找树 xff1f 比如 xff1a 转换成双向链表的顺序是 xff1a 1 3
  • C++算法题:递归和栈的算法

    问题1 xff1a 跳台阶问题 具体描述 xff0c 一个台阶总共有n级 xff0c 如果一次可以跳1级 xff0c 也可以跳2级 求总共有多少总跳法 xff0c 并分析算法的时间杂度 相当于从下往上跳 xff0c 最后剩一个 xff08
  • Linux的.service服务 实现程序开机自启

    一 service文件的位置 所有可用的单元文件存放在 lib systemd system 和 etc systemd system 目录 我们需要在 lib systemd system 下存放 service文件 xff0c 当sys
  • 计算机网络 复习提纲(完整版)

    第一章 概述 计算机网络 xff1a 利用通信线路和通信设备 xff0c 将地理位置和功能不同的多台计算机互联起来 xff0c 用完善的网络软件实现资源共享和信息传递的网络 组成 xff1a 计算机 xff0c 网络操作系统 xff0c 传
  • 无人机多任务寻径仿真软件与实验平台(一)

    项目背景 xff1a 近年来 xff0c 无人机的应用领域已经得到了极大的拓展 xff0c 旋翼无人机凭借较大的载荷 xff0c 稳定的飞行状态与对高空环境的高度适应 xff0c 成为了应用最为广泛的一类无人机 在欧洲 xff0c 北美洲等

随机推荐

  • 无人机实验平台(七) 实验平台的坐标转换(上)

    为什么要做坐标转换 xff1f 大疆提供的sdk中指出 xff0c 无人机通常情况下通过两个坐标系来控制方向 xff1a 自身坐标系 xff08 Body xff09 和地面坐标系 xff08 N E D xff09 这两个坐标系可以相互转
  • 无人机实验平台(十) 室内悬停问题

    VirtualStick Mode VirtualStick Mode是Sdk提供的一种底层控制模式 xff0c 通过模拟物理摇杆的运动向无人机按照一定频率发送摇杆差分信息 xff0c 使得无人机按照类似于被物理摇杆控制的方式运行 xff0
  • 第30章 ADC—电压采集—零死角玩转STM32-F429系列

    第30章 ADC 电压采集 全套 200 集视频教程和 1000 页 PDF 教程请到秉火论坛下载 xff1a www firebbs cn 野火视频教程优酷观看网址 xff1a http i youku com firege 本章参考资料
  • 大数据安全考试提纲

    范围划得虽大 xff0c 但是主题不多 xff0c 和往常一样记录一下重点 考试范围 1 大数据安全概念及目标 2 传统访问控制技术和基于密码的访问控制技术 3 角色挖掘的算法 4 对称密码 xff0c 非对称密码 xff0c hash算法
  • 算法设计与分析(小总结)

    原先一直没注意这一门 xff0c 大概是因为学这些算法的时候 xff0c 板子都不知道背多少遍了 可是考试毕竟不一样 xff0c 如果来个证明很容易抓瞎 看了往年的试题 xff0c 可能确实因为难度高 xff0c 范围一缩再缩 xff0c
  • 软件测试技术

    引论 为什么进行软件测试 xff1f 软件存在缺陷 xff0c 只有通过测试才可以发现缺陷 xff0c 只有发现缺陷才能把缺陷从产品中清除出去 软件中缺陷带来的损失是巨大的 测试是所有工程学科的基本组成单元 软件测试 xff1a 验证 43
  • c语言自定义tcp协议实现socket通信(windows版本)

    前面一篇博客介绍了mac linux下通过C语言自定义协议实现socket通信的示例 xff0c 因为大部分api与windows还有很多区别 xff0c 这里就特意把windows下的tcp通信实例给介绍一下 无论是linux xff0c
  • opencv for java给图片添加水印中文问题

    opencv提供的给图片添加文字的方法Imgproc putText 可以给图片添加文字 xff0c 最后类似一个添加水印的效果 xff0c 但是这个方法对中文支持不好 xff0c 在没有字体支持的情况下 xff0c 默认中文显示 如下图所
  • 社区版Intellij IDEA安装Spring Boot Assistant插件解决yml无提示问题

    如题所示 xff0c 我们如果个人使用免费社区版的IDEA xff0c 它缺失了很多功能 xff0c 使用起来没有专业版那么强大 xff0c 比如无法直接创建springbootinit项目 xff0c spring配置yml文件没有提示
  • IDEA安装spotbugs插件替代findbugs插件

    相信最近想在IDEA上安装findbugs插件的朋友 xff0c 遇到与我一样的问题 xff0c findbugs与IDEA不兼容 xff1a https plugins jetbrains com plugin 3847 findbugs
  • 第40章 CAN—通讯实验—零死角玩转STM32-F429系列

    第40章 CAN 通讯实验 全套 200 集视频教程和 1000 页 PDF 教程请到秉火论坛下载 xff1a www firebbs cn 野火视频教程优酷观看网址 xff1a http i youku com firege 本章参考资料
  • easyexcel读取excel合并单元格数据

    普通的excel列表 xff0c easyexcel读取是没有什么问题的 但是 xff0c 如果有合并单元格 xff0c 那么它读取的时候 xff0c 能获取数据 xff0c 但是数据是不完整的 如下所示的单元格数据 xff1a 我们通过简
  • clion + opencv环境搭建

    clion是一个jetbrains提供的c 43 43 开发环境 xff0c 和idea pycharm等开发工具类似 xff0c 界面有很多相似的地方 clion内置了一个mingw的编译环境 xff0c 自带了gcc g 43 43 等
  • ChatGLM-6B本地cpu部署

    ChatGLM 6B是清华团队研发的机器人对话系统 xff0c 类似ChatGPT xff0c 但是实际相差很多 xff0c 可以当作一个简单的ChatGPT ChatGLM部署默认是支持GPU加速 xff0c 内存需要32G以上 普通的机
  • java通过HttpServletRequest获取post请求中的body内容

    在java web应用中 xff0c 我们如何获取post请求body中的内容 xff1f 以及需要注意的问题 通常利用request获取参数可以直接通过req getParameter name 的方式获取url上面或者ajax data
  • Your password does not satisfy the current policy requirements解决办法

    mysql5 7 x安装以后 xff0c 想修改随机生成的密码为简单容易记忆的密码 xff0c 如root 123456等 xff0c 这时候通过修改密码的几种方式都不行 xff0c 出现密码不符合当前安全策略要求 为了解决这种问题 xff
  • 用一条SQL语句查询出每门课都大于80分的学生姓名

    两道sql题 xff1a 1 用一条SQL语句查询出每门课都大于80分的学生姓名 2 删除除了自动编号不同 xff0c 其他都相同的学生冗余信息 第一题数据如下 xff1a 分析 xff1a 每门课都大于80分 xff0c 就是说学生最低分
  • ajax通过post方法传数组

    ajax在web项目开发中经常会用到 xff0c 平时我们传递数据 xff0c 基本都是一个参数名对应一个参数值 xff0c 后端通过参数名就可以得到参数 xff0c 从而进行相关逻辑处理 xff0c 但是有时候我们会遇到批量操作 xff0
  • “操作无法完成因为其中的文件夹或文件已在另一个程序中打开”解决办法

    在windows系统中 xff0c 我们经常会遇到这样一个问题 xff1a 删除某一个文件或者文件夹 xff0c 被提醒 xff1a 操作无法完成 xff0c 因为其中的文件夹或文件已在另一个程序中打开 这个时候我们一般会先检查是否真的有程
  • 几种常见mybatis分页实现

    mybatis框架分页实现 xff0c 有几种方式 xff0c 最简单的就是利用原生的sql关键字limit来实现 xff0c 还有一种就是利用interceptor来拼接sql xff0c 实现和limit一样的功能 xff0c 再一个就