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();
}
}
mybatis在mysql中的分页扩展的更多相关文章
- mybatis在oracle中的分页扩展
applicationContext.xml <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlS ...
- [数据库]Oracle和mysql中的分页总结
Mysql中的分页 物理分页 •在sql查询时,从数据库只检索分页需要的数据 •通常不同的数据库有着不同的物理分页语句 •mysql物理分页,采用limit关键字 •例如:检索11-20条 selec ...
- MySQL中的分页操作结合python
mysql中的分页操作结合python --分页: --方式1: ;-- 读取十行 , --从第十行读取 往后再读十行 --方式2: offset ; --从第二十行开始读取10行 -- 结合pyth ...
- MySQL中的空间扩展
目录 19.1. 前言 19.2. OpenGIS几何模型 19.2.1. Geometry类的层次 19.2.2. 类Geometry 19.2.3. 类Point 19.2.4. 类Curve 1 ...
- Mysql中的分页处理
先来说一下Mysql中limit的语法: --语法: SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset --举例: selec ...
- MySQL中地理位置数据扩展geometry的使用心得
最近学习了些MySQL geometry数据存储和计算,在这里记录下. 1. 环境 geometry推荐在5.6版本以上使用,尽管大部分功能在5.5已经可用,除了距离计算函数st_distance等新 ...
- 优化 MySQL 中的分页
英文:Robert Eisele 译者:Giraffe 链接:http://yemengying.com/2016/05/28/optimized-pagiantion-mysql/ 一道面试的问题, ...
- PHP+MySQL中实现分页
你只需要在需要添加页的页面加入这几行代码 <?phpinclude 'form.class.php'; $p=new Page(100, 'Demo01.php');//这里需要传递两个参数,参 ...
- Mybatis对MySQL中BLOB字段的读取
1.在sqlMapConfig中,定义一个typeHandlers <typeHandlers> <typeHandler jdbcType="BLOB" jav ...
随机推荐
- 爬虫Scrapy指令学习
1.新建一个新的爬虫项目指令 scrapy startproject xxx 2.在项目/spider目录下创建一个名为XXX的爬虫,并指定爬取域的范围 scrapy genspider XXX & ...
- 红帽子系统链接加vm15秘钥一份
vm15秘钥:YZ718-4REEQ-08DHQ-JNYQC-ZQRD0 红帽子系统下载链接:http://www.ddooo.com/softdown/60964.htm
- Sentinel 哨兵 实现redis高可用
本文链接:http://www.cnblogs.com/zhenghongxin/p/8885879.html 我们知道redis是有主从复制的,例如下图: 但如果master主进程挂掉之后,没有sl ...
- 一个Unix内核级别漏洞(一)
翻译原创稿件,prison整理翻译,首发ichunqiu,原地址:http://lsd-pl.net/kernelvuln.pdf 这是一篇关于Unix内核级别漏洞的paper,由某团队发布在一次黑客 ...
- 再看javascript执行上下文、变量对象
突然看到一篇远在2010年的老文,作者以章节的形式向我们介绍了ECMA-262-3的部分内容,主要涉及到执行上下文.变量对象.作用域.this等语言细节.内容短小而精悍,文风直白而严谨,读完有酣畅淋漓 ...
- JMeter基础:请求参数Parameters 、Body Data的区别
使用Jmeter测试时,很多人不知道请求参数Parameters .Body Data的区别和用途,这里简单介绍下 先了解一个接口的基本概念 在客户机和服务器之间进行请求-响应时,HTTP协议中包括G ...
- byte范围及8种常见数据类型
byte范围:-128 到 127 原因 : 在计算机内,定点数有3种表示法:原码.反码和补码 原码 :二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小. 反码 ...
- 前端 day 30 html 基础一
前情提要: html基础一 一:html标签入门 1: 1 HTML结构 1)一个html文件有且只有一个html标签.这个就是HTML的根标签.2)一个HTML文件主要由两部分组成:文件头和文件体. ...
- Python小白学习之路(十九)—【文件操作步骤】【文件操作模式】
一.文件操作步骤 step1:打开文件,得到文件句柄并赋值给一个变量step2:通过句柄对文件进行操作step3:关闭文件 举例: a = open('hello world', 'r', encod ...
- leetcode-166-分数到小数(用余数判断有没有出现小数的循环体)
题目描述: 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数. 如果小数部分为循环小数,则将循环的部分括在括号内. 示例 1: 输入: n ...