// Path: src/main/java/com/aibibang/common/persistence/dialect/Dialect.java
// public interface Dialect {
// 
//     /**
//      * 数据库本身是否支持分页当前的分页查询方式
//      * 如果数据库不支持的话，则不进行数据库分页
//      *
//      * @return true：支持当前的分页查询方式
//      */
//     public boolean supportsLimit();
// 
//     /**
//      * 将sql转换为分页SQL，分别调用分页sql
//      *
//      * @param sql    SQL语句
//      * @param offset 开始条数
//      * @param limit  每页显示多少纪录条数
//      * @return 分页查询的sql
//      */
//     public String getLimitString(String sql, int offset, int limit);
// 
// }
// 
// Path: src/main/java/com/aibibang/common/persistence/dialect/DialectFactory.java
// public class DialectFactory {
// 	
//     public static Dialect getDialect(Connection connection) {
//         
//     	Dialect dialect = null;
//     	
//     	try {
// 			
//     		DatabaseMetaData md = connection.getMetaData();
//             String dbType = md.getDatabaseProductName().toLowerCase();
//             if ("db2".equals(dbType)){
//             	dialect = new DB2Dialect();
//             }else if("derby".equals(dbType)){
//             	dialect = new DerbyDialect();
//             }else if("h2".equals(dbType)){
//             	dialect = new H2Dialect();
//             }else if("hsql".equals(dbType)){
//             	dialect = new HSQLDialect();
//             }else if("mysql".equals(dbType)){
//             	dialect = new MySQLDialect();
//             }else if("oracle".equals(dbType)){
//             	dialect = new OracleDialect();
//             }else if("postgre".equals(dbType)){
//             	dialect = new PostgreSQLDialect();
//             }else if("mssql".equals(dbType) || "sqlserver".equals(dbType)){
//             	dialect = new SQLServer2005Dialect();
//             }else if("sybase".equals(dbType)){
//             	dialect = new SybaseDialect();
//             }
//             if (dialect == null) {
//                 throw new RuntimeException("mybatis dialect error.");
//             }
// 		} catch (Exception e) {
// 			
// 			e.printStackTrace();
// 		}
//     	
//         return dialect;
//     }
// }


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import org.apache.ibatis.executor.parameter.ParameterHandler;
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.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.RowBounds;
import org.apache.log4j.Logger;
import com.aibibang.common.persistence.dialect.Dialect;
import com.aibibang.common.persistence.dialect.DialectFactory;
package com.aibibang.common.persistence;





/**
 * 分页拦截器
 * 
 * @author King
 *
 */
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PaginationInterceptor implements Interceptor {

    private final static Logger logger = Logger.getLogger(PaginationInterceptor.class);

    private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
    private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        ParameterHandler parameterHandler = statementHandler.getParameterHandler();
        BoundSql boundSql = statementHandler.getBoundSql();
        
        MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
        RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
        String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
        logger.info("SQL : " + CountSqlHelper.getLineSql(originalSql));
        // 没有分页参数
        if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
            return invocation.proceed();
        }
        
        // 获取总记录数
        Page<?> page = (Page<?>) rowBounds;
        
        //Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
        //Dialect dialect = DialectFactory.buildDialect(configuration);
        //String countSql = dialect.getCountString(originalSql);
        
        Connection connection = (Connection) invocation.getArgs()[0];
// Path: src/main/java/com/aibibang/common/persistence/dialect/Dialect.java
// public interface Dialect {
// 
//     /**
//      * 数据库本身是否支持分页当前的分页查询方式
//      * 如果数据库不支持的话，则不进行数据库分页
//      *
//      * @return true：支持当前的分页查询方式
//      */
//     public boolean supportsLimit();
// 
//     /**
//      * 将sql转换为分页SQL，分别调用分页sql
//      *
//      * @param sql    SQL语句
//      * @param offset 开始条数
//      * @param limit  每页显示多少纪录条数
//      * @return 分页查询的sql
//      */
//     public String getLimitString(String sql, int offset, int limit);
// 
// }
// 
// Path: src/main/java/com/aibibang/common/persistence/dialect/DialectFactory.java
// public class DialectFactory {
// 	
//     public static Dialect getDialect(Connection connection) {
//         
//     	Dialect dialect = null;
//     	
//     	try {
// 			
//     		DatabaseMetaData md = connection.getMetaData();
//             String dbType = md.getDatabaseProductName().toLowerCase();
//             if ("db2".equals(dbType)){
//             	dialect = new DB2Dialect();
//             }else if("derby".equals(dbType)){
//             	dialect = new DerbyDialect();
//             }else if("h2".equals(dbType)){
//             	dialect = new H2Dialect();
//             }else if("hsql".equals(dbType)){
//             	dialect = new HSQLDialect();
//             }else if("mysql".equals(dbType)){
//             	dialect = new MySQLDialect();
//             }else if("oracle".equals(dbType)){
//             	dialect = new OracleDialect();
//             }else if("postgre".equals(dbType)){
//             	dialect = new PostgreSQLDialect();
//             }else if("mssql".equals(dbType) || "sqlserver".equals(dbType)){
//             	dialect = new SQLServer2005Dialect();
//             }else if("sybase".equals(dbType)){
//             	dialect = new SybaseDialect();
//             }
//             if (dialect == null) {
//                 throw new RuntimeException("mybatis dialect error.");
//             }
// 		} catch (Exception e) {
// 			
// 			e.printStackTrace();
// 		}
//     	
//         return dialect;
//     }
// }


// Path: src/main/java/com/aibibang/common/persistence/PaginationInterceptor.java
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import org.apache.ibatis.executor.parameter.ParameterHandler;
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.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.RowBounds;
import org.apache.log4j.Logger;
import com.aibibang.common.persistence.dialect.Dialect;
import com.aibibang.common.persistence.dialect.DialectFactory;

package com.aibibang.common.persistence;





/**
 * 分页拦截器
 * 
 * @author King
 *
 */
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PaginationInterceptor implements Interceptor {

    private final static Logger logger = Logger.getLogger(PaginationInterceptor.class);

    private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
    private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        ParameterHandler parameterHandler = statementHandler.getParameterHandler();
        BoundSql boundSql = statementHandler.getBoundSql();
        
        MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
        RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
        String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
        logger.info("SQL : " + CountSqlHelper.getLineSql(originalSql));
        // 没有分页参数
        if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
            return invocation.proceed();
        }
        
        // 获取总记录数
        Page<?> page = (Page<?>) rowBounds;
        
        //Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
        //Dialect dialect = DialectFactory.buildDialect(configuration);
        //String countSql = dialect.getCountString(originalSql);
        
        Connection connection = (Connection) invocation.getArgs()[0];
        Dialect dialect = DialectFactory.getDialect(connection);