gbase(Informix) pageHelper修改分页语句

Posted w329636271

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gbase(Informix) pageHelper修改分页语句相关的知识,希望对你有一定的参考价值。

由于pageHelper生成的sql语句含有子查询导致的sql执行效率太慢;其生成sql如下
SELECT SKIP ? FIRST ? * FROM (select xxx from table ) TEMP_T
;其语句中包含了子查询;我们需要将其改为没有子查询语句的sql 如下:
select SKIP ? FIRST ? xxx from table

修改过程如下:
在项目中新增如下类,注意包名,类名必须一致,才能覆盖原本jar中的类;

package com.github.pagehelper.dialect.helper;

import com.github.pagehelper.Page;
import com.github.pagehelper.dialect.AbstractHelperDialect;
import com.github.pagehelper.util.MetaObjectUtil;
import com.github.pagehelper.util.StringUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.RowBounds;


public class InformixDialect extends AbstractHelperDialect 

  @Override
  public Object processPageParameter(
      MappedStatement ms,
      Map<String, Object> paramMap,
      Page page,
      BoundSql boundSql,
      CacheKey pageKey) 
    paramMap.put(PAGEPARAMETER_FIRST, page.getStartRow());
    paramMap.put(PAGEPARAMETER_SECOND, page.getPageSize());
    // 处理pageKey
    pageKey.update(page.getStartRow());
    pageKey.update(page.getPageSize());
    // 处理参数配置
    if (boundSql.getParameterMappings() != null) 
      List<ParameterMapping> newParameterMappings = new ArrayList<ParameterMapping>();
      if (page.getStartRow() > 0) 
        newParameterMappings.add(
            new ParameterMapping.Builder(ms.getConfiguration(), PAGEPARAMETER_FIRST, Integer.class)
                .build());
      
      if (page.getPageSize() > 0) 
        newParameterMappings.add(
            new ParameterMapping.Builder(ms.getConfiguration(), PAGEPARAMETER_SECOND, Integer.class)
                .build());
      
      if (boundSql != null && boundSql.getParameterMappings() != null) 
        newParameterMappings.addAll(boundSql.getParameterMappings());
      
      MetaObject metaObject = MetaObjectUtil.forObject(boundSql);
      metaObject.setValue("parameterMappings", newParameterMappings);
    
    return paramMap;
  

  @Override
  public String getPageSql(String sql, Page page, CacheKey pageKey) 

    String result = null;
    String lowerCaseSql = sql.toLowerCase();
    int selectIndex = lowerCaseSql.indexOf("select");
    if (selectIndex > -1) 
      StringBuilder sqlBuilder = new StringBuilder(sql.length() + 40);
      if (page.getStartRow() > 0) 
        sqlBuilder.append(" SKIP ? ");
      
      if (page.getPageSize() > 0) 
        sqlBuilder.append(" FIRST ? ");
      
      result =
          sql.substring(0, selectIndex + 6)
              + sqlBuilder.toString()
              + " "
              + sql.substring(selectIndex + 6);
    

    return result;
  

 @Override
  public String getCountSql(MappedStatement ms, BoundSql boundSql, Object parameterObject,
      RowBounds rowBounds, CacheKey countKey) 
    Page<Object> page = getLocalPage();
    String countColumn = page.getCountColumn();
    if (StringUtil.isNotEmpty(countColumn)) 
      return getSmartCountSql(boundSql.getSql(), countColumn);
    
    return countSqlParser.getSmartCountSql(boundSql.getSql());
  

  /**
   * 获取智能的countSql
   *
   * @param sql
   * @param name 列名,默认 0
   * @return
   */
  public String getSmartCountSql(String sql, String name) 
    //解析SQL
    Statement stmt = null;
    //特殊sql不需要去掉order by时,使用注释前缀
    if(sql.indexOf(CountSqlParser.KEEP_ORDERBY) >= 0)
      return countSqlParser.getSimpleCountSql(sql);
    
    try 
      SQLStatement sqlStatement = SQLUtils.parseSinglemysqlStatement(sql);
      SQLSelectStatement selectStatement = (SQLSelectStatement) sqlStatement;
      List<SQLSelectItem> selectList = ( selectStatement).getSelect().getQueryBlock()
          .getSelectList();
      selectList.clear();
      SQLAggregateExpr count = new SQLAggregateExpr("count");
      count.addArgument(new SQLIntegerExpr(1));
      SQLSelectItem sqlSelectItem = new SQLSelectItem(count);
      selectList.add(sqlSelectItem);
      selectStatement.getSelect().getQueryBlock().setOrderBy(null);
      return sqlStatement.toString();
     catch (Throwable e) 
      //无法解析的用一般方法返回count语句
      return countSqlParser.getSimpleCountSql(sql);
    

  

main方法的类中加入加载

  static 
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    if (classLoader == null) 
      classLoader = AdminApplication.class.getClassLoader();
    
    boolean initialize = false;
    try 
      Class
          .forName("com.github.pagehelper.dialect.helper.InformixDialect", initialize, classLoader);
     catch (ClassNotFoundException e) 
      throw new Error("init error. " + e.toString());
    
  

另外发现cout语句也是用子查询语句;可以通过在xml中直接重写count语句即可;例如


 <select id="findUploadList_COUNT"            
    parameterType="Vo"
            resultType="Long">
        select count(1) from tb1 ul
        left join bt2 on tb1.id = tb2.id        
    </select>

以上是关于gbase(Informix) pageHelper修改分页语句的主要内容,如果未能解决你的问题,请参考以下文章

gbase(Informix) pageHelper修改分页语句

pagehelper分页原理浅析

pagehelper总条数最大7设置

pagehelper怎么计算总数的

informix 锁表问题

informix SQL查询咨询