拦截器实现分页

PageHelper.java

import   java.util.List;
import   java.util.Map.Entry;
import   java.util.Properties;
import   java.util.Set;
 
import   org.apache.ibatis.binding.MapperMethod.ParamMap;
import   org.apache.ibatis.executor.Executor;
import   org.apache.ibatis.mapping.MappedStatement;
import   org.apache.ibatis.mapping.SqlSource;
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.ResultHandler;
import   org.apache.ibatis.session.RowBounds;
import   org.springframework.beans.BeanUtils;
 
import   com.ai.sipom.sjfw.data.query.interfaces.vo.page.Page;
import   com.ai.sipom.sjfw.data.query.server.util.SystemConfig;
import   com.ai.sipom.sjfw.data.query.server.util.db.DbContextHolder;
 
/**
  * Mybatis - 通用分页拦截器
  *
  * @author 
  * @version 3.3.0
  * @createdate 2018年01月03日
  */
@SuppressWarnings ({  "rawtypes" "unchecked"   })
@Intercepts ( @Signature (type = Executor. class , method =  "query" , args = {
         MappedStatement. class , Object. class , RowBounds. class ,
         ResultHandler. class   }))
public   class   PageHelper  implements   Interceptor {
     // sql工具类
     private   static   SqlUtil SQLUTIL =  null ;
 
     /**
      * Mybatis拦截器方法
      *
      * @param invocation
      *            拦截器入参
      * @return 返回执行结果
      * @throws Throwable
      *             抛出异常
      */
     public   Object intercept(Invocation invocation)  throws   Throwable {
         final   Object[] args = invocation.getArgs();
 
         Page<?> page =  null ;
         int   flag =  0 ;
         if   (args[ 1 instanceof   ParamMap) {
             Set<Entry> entrySet = ((ParamMap) args[ 1 ]).entrySet();
             for   (Entry entry : entrySet) {
                 if   (entry.getValue()  instanceof   Page) {
                     page = (Page<?>) entry.getValue();
                     break ;
                 }
             }
             flag =  1 ;
         else   if   (((MappedStatement) args[ 0 ]).getId().matches( ".*Page$" )) {
             Integer pageNum = (Integer) BeanUtils.getPropertyDescriptor(args[ 1 ].getClass(),  "pageNum" ).getReadMethod().invoke(args[ 1 ],  new   Object[ 0 ]);
             Integer pageSize = (Integer) BeanUtils.getPropertyDescriptor(args[ 1 ].getClass(),  "pageSize" ).getReadMethod().invoke(args[ 1 ],  new   Object[ 0 ]);
              
             page =  new   Page(pageNum, pageSize);
             flag =  2 ;
         }
          
         if   (page !=  null ) {
             // 忽略RowBounds-否则会进行Mybatis自带的内存分页
             args[ 2 ] = RowBounds.DEFAULT;
             // 获取原始的ms
             MappedStatement ms = (MappedStatement) args[ 0 ];
              
             SqlSource sqlSource = ms.getSqlSource();
             // 将参数中的MappedStatement替换为新的qs
             SQLUTIL.processCountMappedStatement(ms, sqlSource, args);
             // 查询总数
             Object totalResult = invocation.proceed();
             // 设置总数
             long   totalCount = ((Integer) ((List) totalResult).get( 0 ))
                     .longValue();
             page.setTotal(totalCount);
             long   totalPage = totalCount / page.getPageSize() + ((totalCount % page.getPageSize() ==  0 ) ?  0   1 );  
             page.setPages(totalPage);  
             // 将参数中的MappedStatement替换为新的qs
             SQLUTIL.processPageMappedStatement(ms, sqlSource, page,
                     args);
             // 执行分页查询
             Object list = invocation.proceed();
             // 得到处理结果
             page.setList((List) list);
              
             //--------------------------
             if   (flag ==  2 ) {
                 PageList pageList =  new   PageList();
                 pageList.setPageNum(page.getPageNum());
                 pageList.setPageSize(page.getPageSize());
                 pageList.setStartRow(page.getStartRow());
                 pageList.setEndRow(page.getEndRow());
                 pageList.setPages(page.getPages());
                 pageList.setTotal(page.getTotal());
                 if   (page.getList() !=  null ) {
                     pageList.addAll(page.getList());
                     //pageList.setList(page.getList());
                 }
                  
                 return   pageList;
             else   if   (flag ==  1 ) {
                 return   list;
             }
         }
          
         // 返回结果
         return   invocation.proceed();
     }
 
     /**
      * 只拦截Executor
      *
      * @param target
      * @return
      */
     public   Object plugin(Object target) {
         if   (target  instanceof   Executor) {
             return   Plugin.wrap(target,  this );
         else   {
             return   target;
         }
     }
 
     /**
      * 设置属性值
      *
      * @param p
      *            属性值
      */
     public   void   setProperties(Properties p) {
         String dialect = SystemConfig.getValue( "jdbc"   + DbContextHolder.getDBType() +  ".dbtype" );
         if   (dialect ==  null ) {
             dialect =  "mysql" // 默认oracle数据库
         }
         SQLUTIL =  new   SqlUtil(dialect);
     }
}

SqlUtil.java

import  java.util.ArrayList;
import  java.util.HashMap;
import  java.util.List;
import  java.util.Map;
import  org.apache.ibatis.builder.SqlSourceBuilder;
import  org.apache.ibatis.builder.StaticSqlSource;
import  org.apache.ibatis.builder.annotation.ProviderSqlSource;
import  org.apache.ibatis.mapping.BoundSql;
import  org.apache.ibatis.mapping.MappedStatement;
import  org.apache.ibatis.mapping.ParameterMapping;
import  org.apache.ibatis.mapping.ResultMap;
import  org.apache.ibatis.mapping.ResultMapping;
import  org.apache.ibatis.mapping.SqlSource;
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.scripting.xmltags.DynamicContext;
import  org.apache.ibatis.scripting.xmltags.DynamicSqlSource;
import  org.apache.ibatis.scripting.xmltags.MixedSqlNode;
import  org.apache.ibatis.scripting.xmltags.SqlNode;
import  org.apache.ibatis.session.Configuration;
import  com.ai.sipom.sjfw.data.query.interfaces.vo.page.Page;
/**
  * Mybatis - sql工具,获取分页和count的MappedStatement,设置分页参数
  *
  * @author
  * @since 3.3.0
  * @createdate 2018年01月03日
  */
@SuppressWarnings ({ "rawtypes" "unchecked" })
public  class  SqlUtil {
     private  static  final  List<ResultMapping> EMPTY_RESULTMAPPING =  new  ArrayList<ResultMapping>( 0 );
     //分页的id后缀
     private  static  final  String SUFFIX_PAGE =  "_PageHelper" ;
     //count查询的id后缀
     private  static  final  String SUFFIX_COUNT = SUFFIX_PAGE +  "_Count" ;
     //第一个分页参数
     private  static  final  String PAGEPARAMETER_FIRST =  "First"  + SUFFIX_PAGE;
     //第二个分页参数
     private  static  final  String PAGEPARAMETER_SECOND =  "Second"  + SUFFIX_PAGE;
     private  static  final  String PROVIDER_OBJECT =  "_provider_object" ;
     private  static  final  ObjectFactory DEFAULT_OBJECT_FACTORY =  new  DefaultObjectFactory();
     private  static  final  ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY =  new  DefaultObjectWrapperFactory();
     /**
      * 反射对象,增加对低版本Mybatis的支持
      *
      * @param object 反射对象
      * @return
      */
     private  static  MetaObject forObject(Object object) {
         return  MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
     }
     private  SqlUtil.Parser sqlParser;
     //数据库方言 - 使用枚举限制数据库类型
     public  enum  Dialect {
         mysql, mariadb, sqlite, oracle, hsqldb, postgresql
     }
     /**
      * 构造方法
      *
      * @param strDialect
      */
     public  SqlUtil(String strDialect) {
         if  (strDialect ==  null  ||  "" .equals(strDialect)) {
             throw  new  IllegalArgumentException( "Mybatis分页插件无法获取dialect参数!" );
         }
         try  {
             Dialect dialect = Dialect.valueOf(strDialect);
             String sqlParserClass =  this .getClass().getPackage().getName() +  ".SqlParser" ;
             try  {
                 //使用SqlParser必须引入jsqlparser-x.x.x.jar
                 Class.forName( "net.sf.jsqlparser.statement.select.Select" );
                 sqlParser = (Parser) Class.forName(sqlParserClass).getConstructor(Dialect. class ).newInstance(dialect);
             catch  (Exception e) {
                 //找不到时,不用处理
             }
             if  (sqlParser ==  null ) {
                 sqlParser = SimpleParser.newParser(dialect);
             }
         catch  (IllegalArgumentException e) {
             String dialects =  null ;
             for  (Dialect d : Dialect.values()) {
                 if  (dialects ==  null ) {
                     dialects = d.toString();
                 else  {
                     dialects +=  ","  + d;
                 }
             }
             throw  new  IllegalArgumentException( "Mybatis分页插件dialect参数值错误,可选值为["  + dialects +  "]" );
         }
     }
     /**
      * 设置分页参数
      *
      * @param parameterObject
      * @param page
      * @return
      */
     public  Map setPageParameter(MappedStatement ms, Object parameterObject, Page page) {
         BoundSql boundSql = ms.getBoundSql(parameterObject);
         return  sqlParser.setPageParameter(ms, parameterObject, boundSql, page);
     }
     /**
      * 处理count查询的MappedStatement
      *
      * @param ms
      * @param sqlSource
      * @param args
      */
     public  void  processCountMappedStatement(MappedStatement ms, SqlSource sqlSource, Object[] args) {
         args[ 0 ] = getMappedStatement(ms, sqlSource, args[ 1 ], SUFFIX_COUNT);
     }
     /**
      * 处理分页查询的MappedStatement
      *
      * @param ms
      * @param sqlSource
      * @param page
      * @param args
      */
     public  void  processPageMappedStatement(MappedStatement ms, SqlSource sqlSource, Page page, Object[] args) {
         args[ 0 ] = getMappedStatement(ms, sqlSource, args[ 1 ], SUFFIX_PAGE);
         //处理入参
         args[ 1 ] = setPageParameter((MappedStatement) args[ 0 ], args[ 1 ], page);
     }
     /**
      * 处理SQL
      */
     public  static  interface  Parser {
         void  isSupportedSql(String sql);
         String getCountSql(String sql);
         String getPageSql(String sql);
         Map setPageParameter(MappedStatement ms, Object parameterObject, BoundSql boundSql, Page page);
     }
     public  static  abstract  class  SimpleParser  implements  Parser {
         public  static  Parser newParser(Dialect dialect) {
             Parser parser =  null ;
             switch  (dialect) {
                 case  mysql:
                 case  mariadb:
                 case  sqlite:
                     parser =  new  MysqlParser();
                     break ;
                 case  oracle:
                     parser =  new  OracleParser();
                     break ;
                 case  hsqldb:
                     parser =  new  HsqldbParser();
                     break ;
                 case  postgresql:
                 default :
                     parser =  new  PostgreSQLParser();
             }
             return  parser;
         }
         public  void  isSupportedSql(String sql) {
             if  (sql.trim().toUpperCase().endsWith( "FOR UPDATE" )) {
                 throw  new  RuntimeException( "分页插件不支持包含for update的sql" );
             }
         }
         /**
          * 获取总数sql - 如果要支持其他数据库,修改这里就可以
          *
          * @param sql 原查询sql
          * @return 返回count查询sql
          */
         public  String getCountSql( final  String sql) {
             isSupportedSql(sql);
             StringBuilder stringBuilder =  new  StringBuilder(sql.length() +  40 );
             stringBuilder.append( "select count(*) from (" );
             stringBuilder.append(sql);
             stringBuilder.append( ") tmp_count" );
             return  stringBuilder.toString();
         }
         /**
          * 获取分页sql - 如果要支持其他数据库,修改这里就可以
          *
          * @param sql 原查询sql
          * @return 返回分页sql
          */
         public  abstract  String getPageSql(String sql);
         public  Map setPageParameter(MappedStatement ms, Object parameterObject, BoundSql boundSql, Page page) {
             Map paramMap =  null ;
             if  (parameterObject ==  null ) {
                 paramMap =  new  HashMap();
             else  if  (parameterObject  instanceof  Map) {
                 paramMap = (Map) parameterObject;
             else  {
                 paramMap =  new  HashMap();
                 //动态sql时的判断条件不会出现在ParameterMapping中,但是必须有,所以这里需要收集所有的getter属性
                 //TypeHandlerRegistry可以直接处理的会作为一个直接使用的对象进行处理
                 boolean  hasTypeHandler = ms.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass());
                 MetaObject metaObject = forObject(parameterObject);
                 //需要针对注解形式的MyProviderSqlSource保存原值
                 if  (ms.getSqlSource()  instanceof  MyProviderSqlSource) {
                     paramMap.put(PROVIDER_OBJECT, parameterObject);
                 }
                 if  (!hasTypeHandler) {
                     for  (String name : metaObject.getGetterNames()) {
                         paramMap.put(name, metaObject.getValue(name));
                     }
                 }
                 //下面这段方法,主要解决一个常见类型的参数时的问题
                 if  (boundSql.getParameterMappings() !=  null  && boundSql.getParameterMappings().size() >  0 ) {
                     for  (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
                         String name = parameterMapping.getProperty();
                         if  (!name.equals(PAGEPARAMETER_FIRST)
                                 && !name.equals(PAGEPARAMETER_SECOND)
                                 && paramMap.get(name) ==  null ) {
                             if  (hasTypeHandler
                                     || parameterMapping.getJavaType().equals(parameterObject.getClass())) {
                                 paramMap.put(name, parameterObject);
                             else  {
                                 paramMap.put(name, metaObject.getValue(name));
                             }
                         }
                     }
                 }
             }
             return  paramMap;
         }
     }
     //Mysql
     private  static  class  MysqlParser  extends  SimpleParser {
         @Override
         public  String getPageSql(String sql) {
             StringBuilder sqlBuilder =  new  StringBuilder(sql.length() +  14 );
             sqlBuilder.append(sql);
             sqlBuilder.append( " limit ?,?" );
             return  sqlBuilder.toString();
         }
         @Override
         public  Map setPageParameter(MappedStatement ms, Object parameterObject, BoundSql boundSql, Page page) {
             Map paramMap =  super .setPageParameter(ms, parameterObject, boundSql, page);
             paramMap.put(PAGEPARAMETER_FIRST, page.getStartRow());
             paramMap.put(PAGEPARAMETER_SECOND, page.getPageSize());
             return  paramMap;
         }
     }
     //Oracle
     private  static  class  OracleParser  extends  SimpleParser {
         @Override
         public  String getPageSql(String sql) {
             StringBuilder sqlBuilder =  new  StringBuilder(sql.length() +  120 );
             sqlBuilder.append( "select * from ( select tmp_page.*, rownum row_id from ( " );
             sqlBuilder.append(sql);
             sqlBuilder.append( " ) tmp_page where rownum <= ? ) where row_id > ?" );
             return  sqlBuilder.toString();
         }
         @Override
         public  Map setPageParameter(MappedStatement ms, Object parameterObject, BoundSql boundSql, Page page) {
             Map paramMap =  super .setPageParameter(ms, parameterObject, boundSql, page);
             paramMap.put(PAGEPARAMETER_FIRST, page.getEndRow());
             paramMap.put(PAGEPARAMETER_SECOND, page.getStartRow());
             return  paramMap;
         }
     }
     //Oracle
     private  static  class  HsqldbParser  extends  SimpleParser {
         @Override
         public  String getPageSql(String sql) {
             StringBuilder sqlBuilder =  new  StringBuilder(sql.length() +  20 );
             sqlBuilder.append(sql);
             sqlBuilder.append( " limit ? offset ?" );
             return  sqlBuilder.toString();
         }
         @Override
         public  Map setPageParameter(MappedStatement ms, Object parameterObject, BoundSql boundSql, Page page) {
             Map paramMap =  super .setPageParameter(ms, parameterObject, boundSql, page);
             paramMap.put(PAGEPARAMETER_FIRST, page.getPageSize());
             paramMap.put(PAGEPARAMETER_SECOND, page.getStartRow());
             return  paramMap;
         }
     }
     //PostgreSQL
     private  static  class  PostgreSQLParser  extends  SimpleParser {
         @Override
         public  String getPageSql(String sql) {
             StringBuilder sqlBuilder =  new  StringBuilder(sql.length() +  14 );
             sqlBuilder.append(sql);
             sqlBuilder.append( " limit ? offset ?" );
             return  sqlBuilder.toString();
         }
         @Override
         public  Map setPageParameter(MappedStatement ms, Object parameterObject, BoundSql boundSql, Page page) {
             Map paramMap =  super .setPageParameter(ms, parameterObject, boundSql, page);
             paramMap.put(PAGEPARAMETER_FIRST, page.getPageSize());
             paramMap.put(PAGEPARAMETER_SECOND, page.getStartRow());
             return  paramMap;
         }
     }
     /**
      * 自定义动态SqlSource
      */
     private  class  MyDynamicSqlSource  implements  SqlSource {
         private  Configuration configuration;
         private  SqlNode rootSqlNode;
         /**
          * 用于区分动态的count查询或分页查询
          */
         private  Boolean count;
         public  MyDynamicSqlSource(Configuration configuration, SqlNode rootSqlNode, Boolean count) {
             this .configuration = configuration;
             this .rootSqlNode = rootSqlNode;
             this .count = count;
         }
         public  BoundSql getBoundSql(Object parameterObject) {
             DynamicContext context =  new  DynamicContext(configuration, parameterObject);
             rootSqlNode.apply(context);
             SqlSourceBuilder sqlSourceParser =  new  SqlSourceBuilder(configuration);
             Class<?> parameterType = parameterObject ==  null  ? Object. class  : parameterObject.getClass();
             SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
             if  (count) {
                 sqlSource = getCountSqlSource(configuration, sqlSource, parameterObject);
             else  {
                 sqlSource = getPageSqlSource(configuration, sqlSource, parameterObject);
             }
             BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
             //设置条件参数
             for  (Map.Entry<String, Object> entry : context.getBindings().entrySet()) {
                 boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());
             }
             return  boundSql;
         }
     }
     /**
      * 自定义ProviderSqlSource,代理方法
      */
     private  class  MyProviderSqlSource  implements  SqlSource {
         private  Configuration configuration;
         private  ProviderSqlSource providerSqlSource;
         /**
          * 用于区分动态的count查询或分页查询
          */
         private  Boolean count;
         private  MyProviderSqlSource(Configuration configuration, ProviderSqlSource providerSqlSource, Boolean count) {
             this .configuration = configuration;
             this .providerSqlSource = providerSqlSource;
             this .count = count;
         }
         @Override
         public  BoundSql getBoundSql(Object parameterObject) {
             BoundSql boundSql =  null ;
             if  (parameterObject  instanceof  Map && ((Map) parameterObject).containsKey(PROVIDER_OBJECT)) {
                 boundSql = providerSqlSource.getBoundSql(((Map) parameterObject).get(PROVIDER_OBJECT));
             else  {
                 boundSql = providerSqlSource.getBoundSql(parameterObject);
             }
             if  (count) {
                 return  new  BoundSql(
                         configuration,
                         sqlParser.getCountSql(boundSql.getSql()),
                         boundSql.getParameterMappings(),
                         parameterObject);
             else  {
                 return  new  BoundSql(
                         configuration,
                         sqlParser.getPageSql(boundSql.getSql()),
                         getPageParameterMapping(configuration, boundSql),
                         parameterObject);
             }
         }
     }
     /**
      * 获取ms - 在这里对新建的ms做了缓存,第一次新增,后面都会使用缓存值
      *
      * @param ms
      * @param sqlSource
      * @param suffix
      * @return
      */
     private  MappedStatement getMappedStatement(MappedStatement ms, SqlSource sqlSource, Object parameterObject, String suffix) {
         MappedStatement qs =  null ;
         try  {
             qs = ms.getConfiguration().getMappedStatement(ms.getId() + suffix);
         catch  (Exception e) {
             //ignore
         }
         if  (qs ==  null ) {
             //创建一个新的MappedStatement
             qs = newMappedStatement(ms, getsqlSource(ms, sqlSource, parameterObject, suffix), suffix);
             try  {
                 ms.getConfiguration().addMappedStatement(qs);
             catch  (Exception e) {
                 //ignore
             }
         }
         return  qs;
     }
     /**
      * 新建count查询和分页查询的MappedStatement
      *
      * @param ms
      * @param sqlSource
      * @param suffix
      * @return
      */
     private  MappedStatement newMappedStatement(MappedStatement ms, SqlSource sqlSource, String suffix) {
         String id = ms.getId() + suffix;
         MappedStatement.Builder builder =  new  MappedStatement.Builder(ms.getConfiguration(), id, sqlSource, ms.getSqlCommandType());
         builder.resource(ms.getResource());
         builder.fetchSize(ms.getFetchSize());
         builder.statementType(ms.getStatementType());
         builder.keyGenerator(ms.getKeyGenerator());
         if  (ms.getKeyProperties() !=  null  && ms.getKeyProperties().length !=  0 ) {
             StringBuilder keyProperties =  new  StringBuilder();
             for  (String keyProperty : ms.getKeyProperties()) {
                 keyProperties.append(keyProperty).append( "," );
             }
             keyProperties.delete(keyProperties.length() -  1 , keyProperties.length());
             builder.keyProperty(keyProperties.toString());
         }
         builder.timeout(ms.getTimeout());
         builder.parameterMap(ms.getParameterMap());
         if  (suffix == SUFFIX_PAGE) {
             builder.resultMaps(ms.getResultMaps());
         else  {
             //count查询返回值int
             List<ResultMap> resultMaps =  new  ArrayList<ResultMap>();
             ResultMap resultMap =  new  ResultMap.Builder(ms.getConfiguration(), id,  int . class , EMPTY_RESULTMAPPING).build();
             resultMaps.add(resultMap);
             builder.resultMaps(resultMaps);
         }
         builder.resultSetType(ms.getResultSetType());
         builder.cache(ms.getCache());
         builder.flushCacheRequired(ms.isFlushCacheRequired());
         builder.useCache(ms.isUseCache());
         return  builder.build();
     }
     /**
      * 判断当前执行的是否为动态sql
      *
      * @param ms
      * @return
      */
     public  boolean  isDynamic(MappedStatement ms) {
         return  ms.getSqlSource()  instanceof  DynamicSqlSource;
     }
     /**
      * 获取新的sqlSource
      *
      * @param ms
      * @param sqlSource
      * @param parameterObject
      * @param suffix
      * @return
      */
     private  SqlSource getsqlSource(MappedStatement ms, SqlSource sqlSource, Object parameterObject, String suffix) {
         //1. 从XMLLanguageDriver.java和XMLScriptBuilder.java可以看出只有两种SqlSource
         //2. 增加注解情况的ProviderSqlSource
         //3. 对于RawSqlSource需要进一步测试完善
         //如果是动态sql
         if  (isDynamic(ms)) {
             MetaObject msObject = forObject(ms);
             SqlNode sqlNode = (SqlNode) msObject.getValue( "sqlSource.rootSqlNode" );
             MixedSqlNode mixedSqlNode =  null ;
             if  (sqlNode  instanceof  MixedSqlNode) {
                 mixedSqlNode = (MixedSqlNode) sqlNode;
             else  {
                 List<SqlNode> contents =  new  ArrayList<SqlNode>( 1 );
                 contents.add(sqlNode);
                 mixedSqlNode =  new  MixedSqlNode(contents);
             }
             return  new  MyDynamicSqlSource(ms.getConfiguration(), mixedSqlNode, suffix == SUFFIX_COUNT);
         else  if  (sqlSource  instanceof  ProviderSqlSource) {
             return  new  MyProviderSqlSource(ms.getConfiguration(), (ProviderSqlSource) sqlSource, suffix == SUFFIX_COUNT);
         }
         //如果是静态分页sql
         else  if  (suffix == SUFFIX_PAGE) {
             //改为分页sql
             return  getPageSqlSource(ms.getConfiguration(), sqlSource, parameterObject);
         }
         //如果是静态count-sql
         else  {
             return  getCountSqlSource(ms.getConfiguration(), sqlSource, parameterObject);
         }
     }
     /**
      * 增加分页参数映射
      *
      * @param configuration
      * @param boundSql
      * @return
      */
     private  List<ParameterMapping> getPageParameterMapping(Configuration configuration, BoundSql boundSql) {
         List<ParameterMapping> newParameterMappings =  new  ArrayList<ParameterMapping>();
         newParameterMappings.addAll(boundSql.getParameterMappings());
         newParameterMappings.add( new  ParameterMapping.Builder(configuration, PAGEPARAMETER_FIRST, Integer. class ).build());
         newParameterMappings.add( new  ParameterMapping.Builder(configuration, PAGEPARAMETER_SECOND, Integer. class ).build());
         return  newParameterMappings;
     }
     /**
      * 获取分页的sqlSource
      *
      * @param configuration
      * @param sqlSource
      * @return
      */
     private  SqlSource getPageSqlSource(Configuration configuration, SqlSource sqlSource, Object parameterObject) {
         BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
         return  new  StaticSqlSource(configuration, sqlParser.getPageSql(boundSql.getSql()), getPageParameterMapping(configuration, boundSql));
     }
     /**
      * 获取count的sqlSource
      *
      * @param sqlSource
      * @return
      */
     private  SqlSource getCountSqlSource(Configuration configuration, SqlSource sqlSource, Object parameterObject) {
         BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
         return  new  StaticSqlSource(configuration, sqlParser.getCountSql(boundSql.getSql()), boundSql.getParameterMappings());
     }
     /**
      * 测试[控制台输出]count和分页sql
      *
      * @param dialet      数据库类型
      * @param originalSql 原sql
      */
     public  static  void  testSql(String dialet, String originalSql) {
         SqlUtil sqlUtil =  new  SqlUtil(dialet);
         String countSql = sqlUtil.sqlParser.getCountSql(originalSql);
         System.out.println(countSql);
         String pageSql = sqlUtil.sqlParser.getPageSql(originalSql);
         System.out.println(pageSql);
     }
}

PageList.java

import  java.util.ArrayList;
/**
  * 分页
 
  * @author
  *
  * @param <E>
  * @createdate 2018年01月03日
  */
public  class  PageList<E>  extends  ArrayList<E> {
     
     /**
     
      */
     private  static  final  long  serialVersionUID = 1L;
     private  Integer pageNum;
     private  Integer pageSize;
     private  Integer startRow;
     private  Integer endRow;
     private  Long total;
     private  Long pages;
     public  PageList() {
     }
     public  PageList(Integer pageNum, Integer pageSize) {
         this .pageNum = pageNum;
         this .pageSize = pageSize;
         this .startRow = pageNum >  0  ? (pageNum -  1 ) * pageSize :  0 ;
         this .endRow = pageNum * pageSize;
     }
     public  Long getPages() {
         return  pages;
     }
     public  void  setPages(Long pages) {
         this .pages = pages;
     }
     public  Integer getEndRow() {
         return  endRow;
     }
     public  void  setEndRow(Integer endRow) {
         this .endRow = endRow;
     }
     public  Integer getPageNum() {
         return  pageNum;
     }
     public  void  setPageNum(Integer pageNum) {
         this .pageNum = pageNum;
     }
     public  Integer getPageSize() {
         return  pageSize;
     }
     public  void  setPageSize(Integer pageSize) {
         this .pageSize = pageSize;
     }
     public  Integer getStartRow() {
         return  startRow;
     }
     public  void  setStartRow(Integer startRow) {
         this .startRow = startRow;
     }
     public  Long getTotal() {
         return  total;
     }
     public  void  setTotal(Long total) {
         this .total = total;
     }
     @Override
     public  String toString() {
         return  "Page{"  +
                 "pageNum="  + pageNum +
                 ", pageSize="  + pageSize +
                 ", startRow="  + startRow +
                 ", endRow="  + endRow +
                 ", total="  + total +
                 ", pages="  + pages +
                 '}' ;
     }
}

Page.java

import  java.io.Serializable;
import  java.util.List;
/**
  * @author
  * @createdate 2018年01月03日
  * */
public  class  Page<T>  implements  Serializable {
    private  static  final  long  serialVersionUID = 1L;
    private  Integer pageNum;
    private  Integer pageSize;
    private  Integer startRow;
    private  Integer endRow;
    private  Long total;
    private  Long pages;
    private  List<T> list;
    public  Page() {
    }
    public  Page(Integer pageNum, Integer pageSize) {
       this .pageNum = pageNum;
       this .pageSize = pageSize;
       this .startRow = Integer.valueOf(pageNum.intValue() >  0 ?(pageNum.intValue() -  1 ) * pageSize.intValue(): 0 );
       this .endRow = Integer.valueOf(pageNum.intValue() * pageSize.intValue());
    }
    public  List<T> getList() {
       return  this .list;
    }
    public  void  setList(List<T> list) {
       this .list = list;
    }
    public  Long getPages() {
       return  this .pages;
    }
    public  void  setPages(Long pages) {
       this .pages = pages;
    }
    public  Integer getEndRow() {
       return  this .endRow;
    }
    public  void  setEndRow(Integer endRow) {
       this .endRow = endRow;
    }
    public  Integer getPageNum() {
       return  this .pageNum;
    }
    public  void  setPageNum(Integer pageNum) {
       this .pageNum = pageNum;
    }
    public  Integer getPageSize() {
       return  this .pageSize;
    }
    public  void  setPageSize(Integer pageSize) {
       this .pageSize = pageSize;
    }
    public  Integer getStartRow() {
       return  this .startRow;
    }
    public  void  setStartRow(Integer startRow) {
       this .startRow = startRow;
    }
    public  Long getTotal() {
       return  this .total;
    }
    public  void  setTotal(Long total) {
       this .total = total;
    }
    public  String toString() {
       return  "Page{pageNum="  this .pageNum +  ", pageSize="  this .pageSize +  ", startRow="  this .startRow +  ", endRow="  this .endRow +  ", total="  this .total +  ", pages="  this .pages +  '}' ;
    }
}

DbContextHolder.java

/**
  * Title: AIDP_SMARTOS <br>
  * Description: 数据源变量存储处,这里是个线程安全的ThreadLocal的包装<br>
  * Date: 2018年01月03日 <br>
  * Copyright (c) 2018 AIDP <br>
  * @author 
  */
public  class  DbContextHolder {
     private  static  final  ThreadLocal<String> contextHolder =  new  ThreadLocal<String>();
     
     public  static  void  setDBType(String dbType) {
         contextHolder.set(dbType);
     }
     
     public  static  String getDBType() {
         return  StringKit.isBlank(contextHolder.get()) ?  ""  : contextHolder.get();
     }
     
     public  static  void  clearDBType() {
         contextHolder.remove();
     }
}

StringKit.java

/**
  * @author
  * @createdate 2018年01月03日
  * */
public  class  StringKit {
    public  static  String javaToDbFieldName(String name) {
       StringBuilder result =  new  StringBuilder();
       if (notBlank(name) && name.indexOf( "_" ) <  0 ) {
          result.append(name.substring( 0 1 ).toLowerCase());
          for ( int  i =  1 ; i < name.length(); ++i) {
             String s = name.substring(i, i +  1 );
             if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt( 0 ))) {
                result.append( "_" );
             }
             result.append(s.toLowerCase());
          }
          return  result.toString();
       else  {
          name = notBlank(name)?name: "" ;
          return  name;
       }
    }
    public  static  String dbToJavaFieldName(String name) {
       StringBuilder result =  new  StringBuilder();
       if (notBlank(name)) {
          name = name.toLowerCase();
          for ( int  i =  0 ; i < name.length(); ++i) {
             String s = name.substring(i, i +  1 );
             if (s.equals( "_" ) && i < name.length() -  1 ) {
                ++i;
                s = name.substring(i, i +  1 );
                result.append(s.toUpperCase());
             else  {
                result.append(s);
             }
          }
       }
       return  result.toString();
    }
    public  static  String firstCharToLowerCase(String str) {
       char  firstChar = str.charAt( 0 );
       if (firstChar >=  65  && firstChar <=  90 ) {
          char [] arr = str.toCharArray();
          arr[ 0 ] = ( char )(arr[ 0 ] +  32 );
          return  new  String(arr);
       else  {
          return  str;
       }
    }
    public  static  String firstCharToUpperCase(String str) {
       char  firstChar = str.charAt( 0 );
       if (firstChar >=  97  && firstChar <=  122 ) {
          char [] arr = str.toCharArray();
          arr[ 0 ] = ( char )(arr[ 0 ] -  32 );
          return  new  String(arr);
       else  {
          return  str;
       }
    }
    public  static  boolean  isBlank(String str) {
       return  str ==  null  ||  "" .equals(str.trim());
    }
    public  static  boolean  notBlank(String str) {
       return  str !=  null  && ! "" .equals(str.trim());
    }
    public  static  boolean  notBlank(String... strings) {
       if (strings ==  null ) {
          return  false ;
       else  {
          String[] arr$ = strings;
          int  len$ = strings.length;
          for ( int  i$ =  0 ; i$ < len$; ++i$) {
             String str = arr$[i$];
             if (str ==  null  ||  "" .equals(str.trim())) {
                return  false ;
             }
          }
          return  true ;
       }
    }
    public  static  boolean  notNull(Object... paras) {
       if (paras ==  null ) {
          return  false ;
       else  {
          Object[] arr$ = paras;
          int  len$ = paras.length;
          for ( int  i$ =  0 ; i$ < len$; ++i$) {
             Object obj = arr$[i$];
             if (obj ==  null ) {
                return  false ;
             }
          }
          return  true ;
       }
    }
    public  static  String escapeNull(String str) {
       return  notBlank(str)?str: "" ;
    }
    public  static  String addSlash(String path) {
       return  path ==  null ? "/" :(path.startsWith( "/" )?path: "/"  + path);
    }
}

BaseSvcUtil.java

import  java.util.ArrayList;
/**
  * 后台服务统一工具类
  * @author 
  * @since 2018年01月03日
  * @history V0.1
  */
public  class  BaseSvcUtil {
     
     public  static  <T> Page<T> getPage(PageList<T> pageList) {
         Page<T> page =  new  Page<T>();
         
         page.setPageNum(pageList.getPageNum());
         page.setPageSize(pageList.getPageSize());
         page.setStartRow(pageList.getStartRow());
         page.setEndRow(pageList.getEndRow());
         page.setPages(pageList.getPages());
         page.setTotal(pageList.getTotal());
         page.setList( new  ArrayList<T>(pageList));
         //page.setList(pageList.getList());
         
         return  page;
     }
}
eg:
public  Page<PatentVO> queryByNamePage(PatentVO patentVO) {
     PageList<PatentVO> pageList = xxxVOMapper.queryByNamePage(patentVO);
     if (pageList!= null )
         return  BaseSvcUtil.getPage(pageList);
     else
         return  null ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值