mybatis在mysql中的分页扩展

applicationContext.xml

	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation" value="classpath:/mybatis-config.xml" />
	</bean>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
		<!-- 设置成 true就可以启动缓存,一般的修改要1分钟才能生效(因为设置的flushInterval="60000" )
			 如果是在一个xxxxMapper.xml里面修改的数据库的数据,就直接清空本mapper的缓存 -->
		<setting name="cacheEnabled" value="false"/>
		<setting name="useGeneratedKeys" value="false"/>
	</settings>
	<plugins>
		<plugin interceptor="com.system.util.DiclectStatementHandlerInterceptor" />
		<plugin interceptor="com.system.util.DiclectResultSetHandlerInterceptor" />
	</plugins>
</configuration>

DiclectResultSetHandlerInterceptor.java

package com.system.util;

import java.sql.Statement;
import java.util.Properties;

import org.apache.ibatis.executor.resultset.FastResultSetHandler;
import org.apache.ibatis.executor.resultset.NestedResultSetHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
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.session.RowBounds;

@Intercepts({ @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = { Statement.class }) })
public class DiclectResultSetHandlerInterceptor implements Interceptor {

	public Object intercept(Invocation invocation) throws Throwable {
		FastResultSetHandler resultSet = (FastResultSetHandler) invocation.getTarget();
		if(!(resultSet instanceof NestedResultSetHandler)) {
			RowBounds rowBounds = (RowBounds) ReflectUtil.getClassField(resultSet, "rowBounds");
			if (rowBounds.getLimit() > 0 && rowBounds.getLimit() < RowBounds.NO_ROW_LIMIT) {
				ReflectUtil.setClassField(resultSet, "rowBounds", new RowBounds());
			}
		}
		return invocation.proceed();
	}

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

	public void setProperties(Properties properties) {}
}

 

DiclectStatementHandlerInterceptor.java

package com.system.util;

import java.sql.Connection;
import java.util.Properties;

import org.apache.ibatis.executor.statement.PreparedStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
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.session.RowBounds;

@Intercepts( { @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class DiclectStatementHandlerInterceptor implements Interceptor {

	public Object intercept(Invocation invocation) throws Throwable {
		RoutingStatementHandler statement = (RoutingStatementHandler) invocation.getTarget();
		StatementHandler handler = (StatementHandler) ReflectUtil.getClassField(statement, "delegate");
		if (handler instanceof PreparedStatementHandler){
			RowBounds rowBounds = (RowBounds) ReflectUtil.getSuperClassField(handler, "rowBounds");
			if (rowBounds.getLimit() > 0 && rowBounds.getLimit() < RowBounds.NO_ROW_LIMIT) {
				BoundSql boundSql = statement.getBoundSql();
				String sql = boundSql.getSql();
				sql = getLimitString(sql, rowBounds.getOffset(), rowBounds.getLimit());
				ReflectUtil.setClassField(boundSql, "sql", sql);
			}
		}
		return invocation.proceed();
	}

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

	public void setProperties(Properties properties) {
	}

	public String getLimitString(String sql, int offset, int limit) {
		limit = offset+limit;
		sql = sql.trim();
		boolean isForUpdate = false;
		if ( sql.toLowerCase().endsWith(" for update") ) {
			sql = sql.substring( 0, sql.length()-11 );
			isForUpdate = true;
		}
		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
		pagingSelect.append(sql);

		pagingSelect.append(" limit "+offset+","+limit);
		if ( isForUpdate ) {
			pagingSelect.append( " for update" );
		}

		return pagingSelect.toString();
	}
}

  

时间: 2024-10-01 00:56:40

mybatis在mysql中的分页扩展的相关文章

mybatis在oracle中的分页扩展

applicationContext.xml <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value=&q

MySQL中的分页操作结合python

mysql中的分页操作结合python --分页: --方式1: select * from ta12 limit 10;-- 读取十行 select * from ta12 limit 10,10 --从第十行读取 往后再读十行 --方式2: select * from ta12 limit 10 offset 20 ; --从第二十行开始读取10行 -- 结合python 分页: page = input('请输入要查看的页码') page = int(page) select * from

Mysql中的分页处理

先来说一下Mysql中limit的语法: --语法: SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset --举例: select * from table limit 5; --返回前5行 select * from table limit 0,5; --同上,返回前5行 select * from table limit 5,10; --返回6-15行 Mysql中分页主要利用limit能够根据偏移量返回结果的特性: s

[数据库]Oracle和mysql中的分页总结

物理分页 •在sql查询时,从数据库只检索分页需要的数据 •通常不同的数据库有着不同的物理分页语句 •mysql物理分页,采用limit关键字 •例如:检索11-20条 select * from user limit 10,10 ; * 每次只查询10条记录.当点击下一页的时候,查询数据库,查询后10条. * 优点:如果数据量非常大,不会导致内存溢出. * 缺点:每次都与数据库进行交互. * 分页一般采用数据库的sql语句完成分页查询. * MYSQL分页:使用limit关键字. * Orac

优化 MySQL 中的分页

英文:Robert Eisele 译者:Giraffe 链接:http://yemengying.com/2016/05/28/optimized-pagiantion-mysql/ 一道面试的问题,当MySQL表中有数据量很大的时候如何做分页....当时只知道在数据量很大的时候可以分表,但不知道不分表时可以怎么做....唉,谁让代理商就那么几条数据,一个简单的limit,offset就完全hold住了(捂脸)... 很多应用往往只展示最新或最热门的几条记录,但为了旧记录仍然可访问,所以就需要个

mybatis存取mysql中的json

mysql 5.7后新增了一个json类型字段,以往json入库都是转字符串,取到前端造成了不少困扰.今天就做了个小例子把这个整合到ssm例子中. 这里插句题外话,因为最近开始改用idea,配置项目的时候出了一大堆问题,这边也顺便说下如果idea在启动tomcat客户端控制台出现乱码处理办法 打开idea安装目录-bin用记事本打开idea.exe.vmoptions和idea64.exe.vmoptions文件在文件后面添加一行:-Dfile.encoding=UTF-8 好了进入整体 第一步

PHP+MySQL中实现分页

你只需要在需要添加页的页面加入这几行代码 <?phpinclude 'form.class.php'; $p=new Page(100, 'Demo01.php');//这里需要传递两个参数,参数一是分页中每页默认要显示的条数,参数二是本页面的链接地址 echo $p->ShowDiv(); ?> 实现分类的页Page.class.php <?php class Page{ private $pageNum; //当前页 private $pageCount; //总页数 priv

mybatis查询mysql的datetime类型数据时间差了14小时

今天使用mybatis查询mysql中的数据时,莫名其妙的所有时间都出错了,所有时间都比数据库时间多了14小时,考虑了一下,初步判定是系统时区的问题.因为mysql时区设置默认是操作系统时区,查看了下centos时区,东8区没有错,所以可以判定是代码里面设置了一个错误的时区. 现在开始调试mybatis源码,调试到mysql-connector-java-6.0.4.jar包的com.mysql.cj.jdbc.io.JdbcTimestampValueFactory的createFromTim

mybatis对mysql进行分页

Mybatis对mysql数据库分页 在generator中增加插件,下载地址http://download.csdn.net/detail/shunlongjin/6937045 <plugintype="org.mybatis.generator.plugins.EqualsHashCodePlugin" /> <plugintype="org.duoku.groom.mybatis.plugin.PaginationPlugin">&l