ibatis基于拦截器的分页实现

ibatis基于拦截器的分页实现

1、在spring配置文件(applicationContext.xml)中添加拦截器配置:



    
        
            com.ifdoo.core.mybatis.dialet.MySQLDialect
            .*query.*
        
    

2、PagePlugin.java



import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import javax.xml.bind.PropertyException;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.statement.BaseStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
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.scripting.defaults.DefaultParameterHandler;

import com.ifdoo.core.exception.SystemException;
import com.ifdoo.core.mybatis.dialet.Dialect;
import com.ifdoo.core.utils.page.PageView;

/**
 * Mybatis的分页查询插件,通过拦截StatementHandler的prepare方法来实现。
 * 只有在参数列表中包括Page类型的参数时才进行分页查询。 在多参数的情况下,只对第一个Page类型的参数生效。
 * 另外,在参数列表中,Page类型的参数无需用@Param来标注
 * 
 * @version 1.0
 */
@SuppressWarnings("unchecked")
@Intercepts( { @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PagePlugin implements Interceptor {

    private static Dialect  dialectObject   = null; // 数据库方言
    private static String   pageSqlId       = "";   // mybaits的数据库xml映射文件中需要拦截的ID(正则匹配)

    @SuppressWarnings("rawtypes")
    public Object intercept(Invocation ivk) throws Throwable {
        if (ivk.getTarget() instanceof RoutingStatementHandler) {
            RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget();
            BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate");
            MappedStatement mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate, "mappedStatement");
            /**
             * 方法1:通过ID来区分是否需要分页..*query.* 方法2:传入的参数是否有page参数,如果有,则分页,
             */
            // if (mappedStatement.getId().matches(pageSqlId)) { // 拦截需要分页的SQL
            BoundSql boundSql = delegate.getBoundSql();
            Object parameterObject = boundSql.getParameterObject();// 分页SQL