mybatis在oracle中的分页扩展

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");
		//PreparedStatementHandler handler = (PreparedStatementHandler) 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 );
		if (offset > 0) {
			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
		}
		else {
			pagingSelect.append("select * from ( ");
		}
		pagingSelect.append(sql);
		if (offset > 0) {
			pagingSelect.append(" ) row_ ) where rownum_ <= " + limit + " and rownum_ > " + offset);
		}
		else {
			pagingSelect.append(" ) where rownum <= " + limit);
		}
		if ( isForUpdate ) {
			pagingSelect.append( " for update" );
		}

		return pagingSelect.toString();
	}
}

  

时间: 2024-10-12 15:30:08

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

mybatis在mysql中的分页扩展

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

MyBatis在Oracle中插入数据并返回主键的问题解决

引言:  在MyBatis中,希望在Oracle中插入数据之时,同时返回主键值,而非插入的条数... 环境:MyBatis 3.2 , Oracle, Spring 3.2   SQL Snippet in XML Configuration: <insert id="insertSelective" parameterType="com.jxxx.p2pp.model.UUserInfo"> <selectKey resultType="

Oracle中经典分页代码!

在Oracle中因为没有top关键字,所以在sqlserver中的分页代码并不适用于Oracle,那么在Oracle中如何来实现分页呢? --查询所有数据 STUNO STUNAME STUAGE STUID STUSEAAT ------ -------------------- ---------- ---------- ---------- 9 王五 15 5.9876E+15 5 13 哈哈 15 5.9876E+15 5 15 李四 12 1.5666E+10 6 1 66 10 55

Mybatis调用Oracle中的存储过程和function

一.Mybatis调用存储过程 1 在数据库中创建以下的存储过程create or replace procedure pro_hello(p_user_name in varchar2,p_result out varchar2) isbegin  p_result := 'hello,' || p_user_name;end; 2 编写SQL映射文件mapper.xmlstatementType里的CALLABLE是标注此sql为存储过程.parameterType是标注要传的参数,看了一些

Mybatis调用Oracle中的函数有返回值

本身这个项目后台是用SSM框架,试了网上好多种有返回值的方法返回都是空; 下面是我调用方法: 这是我的函数 我在Mybatis的写法是: SELECT DEAL_EBOND_ICODE_DATA(#{iCode,jdbcType=VARCHAR}) AS A from dual 在DAO层 这种写法可以直接获取返回值,而且和其他一般的方法没什么区别! 原文地址:https://www.cnblogs.com/zhangqb/p/11137409.html

Oracle中的分页代码

SELECT * FROM (SELECT ENAME,SAL,ROWNUM RN FROM EMP WHERE ROWNUM <= @CURRENTPAGE*@PAGESIZE) SUB WHERE SUB.RN > (@CURRENTPAGE-1)*5;

基于mybatis向oracle中插入数据的性能对比

数据库表结构: 逐条插入sql语句: <insert id="insert" parameterType="com.Structure"> INSERT INTO STRUCTURE( id, structureNAME, PARENTID, structureType, description, deptId, propertyCompanyId, sort, communityId) VALUES( #{id,jdbcType=VARCHAR}, #

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

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

Oracle的查询-分页查询

--Oracle中的分页 --rownum行号:当我们做select操作时候 --每查询出一行记录,就在该行加上一个行号 --行号从1开始,一次递增,不能跳着走 ----emp表工资倒叙排列后,每页5条记录.查询第二页 ----排序操作会影响rownum的顺序 ----如果涉及到排序,但是还要用rownum的话.使用嵌套查询 ----rownum行号不能写大于一个正数 select * from( select rownum rn, e.* from( select * from emp ord