我是参考公司框架,以及网上资料整理的,希望大家能细化或者指点。
package com.botech.skynet.common;
import java.sql.Connection;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.executor.statement.StatementHandler;
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;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.springframework.util.StringUtils;
//import com.botech.skynet.comm.qvo.DataGridQO;
@Intercepts({@Signature(type =StatementHandler.class, method = "prepare", args ={Connection.class})})
public class PaginationInterceptor implements Interceptor {
Log log= LogFactory.getLog(LogFactory.class);
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
//MetaObject是Mybatis提供的一个的工具类,通过它包装一个对象后可以获取或设置该对象的原本不可访问的属性(比如那些私有属性)。
MetaObject metaStatementHandler = MetaObject.forObject(statementHandler,SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY);
//判断是否使用分页,如果不判断,那么所有的sql将会给予分页
RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
return invocation.proceed();
}
//获取原始sql
String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
//获取mybatis配置参数
Configuration configuration = (Configuration) metaStatementHandler
.getValue("delegate.configuration");
String dialect= (String) configuration.getVariables().get("dialect");
//获取参数d
DefaultParameterHandler defaultParameterHandler = (DefaultParameterHandler) metaStatementHandler
.getValue("delegate.parameterHandler");
PageObject dtQo = null;
Object sidx = null;
Object sord = null;
if(defaultParameterHandler.getParameterObject() instanceof PageObject){
dtQo = (PageObject) defaultParameterHandler.getParameterObject();
sidx = dtQo.getSort();
sord = dtQo.getOrder();
}else{
Map parameterMap = (Map) defaultParameterHandler.getParameterObject();
sidx = parameterMap.get("_sidx");
sord = parameterMap.get("_sord");
}
OracleDialect oracle = new OracleDialect();
if(dialect.equalsIgnoreCase("oracle") ){
metaStatementHandler.setValue("delegate.boundSql.sql", oracle
.getLimitString(originalSql, rowBounds.getOffset(), rowBounds
.getLimit()));
log.info("分页成功--------------------------------->");
}else{
return invocation.proceed();
}
metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
// 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
@Override
public void setProperties(Properties target) {
// TODO Auto-generated method stub
}
}
配置文件spring
<description>spring配置</description>
<!-- 加载数据库文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:config.properties" />
</bean>
<!-- 配置数据库dbcp池链接 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="${initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${maxWait}"></property>
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id ="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="select*" read-only="true"/>
<tx:method name="queryFor*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 拦截器分页mybatis -->
<bean id="paginationInterceptor" class="com.botech.skynet.common.PaginationInterceptor"/>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
<property name="dataSource" ref="dataSource"></property>
<!-- 自动扫描mapping.xml文件 删除正常 -->
<property name="mapperLocations" value="classpath:com/botech/skynet/base/persistence/*.xml" />
<property name="plugins">
<array>
<ref bean="paginationInterceptor"/>
</array>
</property>
<property name="configurationProperties">
<props>
<prop key="dialect">oracle</prop>
</props>
</property>
</bean>
<!-- 配置sqlSessionTemplate -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<!-- 配置mybatis的sqlMap及接口的映射 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.botech.skynet.base.persistence"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<!-- 扫描控件,不包括controller -->
<context:component-scan base-package="com.botech">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>