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

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

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 串口服务器调试助手使用教程,串口服务器如何配置及串口调试6大技巧

    串口服务器调试助手使用教程,串口服务器如何配置及串口调试6大技巧串口服务器如何配置相信很多用户不是很清楚;今天就针对串口服务器如何配置以及串口调试的6大技巧,加以总结阐述:1、如何设置串行服务器的串行端口属性,例如波特率具体参数及数值大小?①点击屏幕上的“设备”单元;②手动打字输入“程序设置”;③再手动选择“程序”,最后手动输入“串行参数”。2、怎样配置串口服务器?首先,必须了解熟悉自身的操作环境与应用配置参数(熟悉每个串行端口的操作模式、熟悉主要参数包括的网…

    2022年5月6日
  • sql-connectionStrings「建议收藏」

    sql-connectionStrings「建议收藏」<connectionStrings><addname=”ClassReservatConnectionString”connectionString=”server=localhost;userid=root;password=123456;database=classreservat;”providerName=”System.Data.SqlClient…

    2022年5月11日
  • centos 6.5 p2v virt-p2v过程详解之一

    centos 6.5 p2v virt-p2v过程详解之一在此就不写关于那些概念和定义了,直接就写出过程一、安装kvmKVM需要有CPU的支持(Intelvmx或AMDsvm),在安装KVM之前检查一下CPU是否提供了虚拟技术的支持:#egrep’^flags.*(vmx|svm)’/proc/cpuinfo有显示,有显示则说明处理器具有VT功能,在主板BIOS中开启CPU的VirtualTechnoleg

    2022年7月26日
  • 安卓7.1精简版下载_asm字节码

    安卓7.1精简版下载_asm字节码ASM 7.1 发布

    2022年4月21日
  • 编译Android 4.4.4 r1的源码刷Nexus 5手机详细教程

    编译Android 4.4.4 r1的源码刷Nexus 5手机详细教程网上关于编译Android源码的教程已经很多了,但是讲怎么编译Android源码刷到真机上的教程不是很多并且也没有讲清楚,仅仅编译Android源码不部署到真机上折腾一下是不愉快的。在Android安全学习的过程不免涉及到修改Android源码过各种对抗的事情,今天有空来学习一下如何编译Android源码部署到谷歌的Nexus5手机上,以Android4.4.4r1的源码为例子,在Ubun

    2022年5月24日
  • hdu 4964 Emmet()模拟

    hdu 4964 Emmet()模拟

    2022年1月12日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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