一个针对不同数据库的分页java代码详解编程语言

import org.apache.log4j.Logger; 
import org.rwl.utils.db.dialect.ExtendDialect; 
import org.rwl.utils.db.dialect.impl.ExtendDB2Dialect; 
import org.rwl.utils.exception.RwlDialectException; 
  
/** 
 * 数据库SQL规则处理 
 * @author polarbear 2009-5-9 
 * 
 */ 
public class RwlDBDialectUtil { 
      
    private volatile static RwlDBDialectUtil instance = null; 
      
    private RwlDBDialectUtil.dbtype currentDialect = RwlDBDialectUtil.dbtype.mysql; 
      
    private String SQL_SERVER_VERSION = "2005"; 
      
    /** 
     * 是否支持分页: 1:支持分页(缺省)  0:不支持分页 
     */ 
    private int SQL_SUPPORT_PAGING = 1; 
      
    /** 
     * 分页处理程序 
     */ 
    public static final ExtendDialect db2Dialect = new ExtendDB2Dialect(); 
      
    private static Logger log = Logger.getLogger(RwlDBDialectUtil.class); 
      
    private RwlDBDialectUtil() { 
        _init(); 
    } 
  
    private void _init() { 
          
    } 
  
    public static RwlDBDialectUtil getInstance() { 
        if (instance == null) { 
            synchronized (RwlDBDialectUtil.class) { 
                if (instance == null) { 
                    instance = new RwlDBDialectUtil(); 
                } 
            } 
        } 
        return instance; 
    } 
      
    /** 
     * 获取分页的SQL语句 
     * @param _sql 基础语句 
     * @param hasOffset 是否限定数量(一般都是true) 
     * @param _start 起始数 
     * @param _limit 限定的数量 
     * @return 返回设定好分页的SQL语句 
     * @throws RwlDialectException 
     */ 
    public String getSqlLimit(String _sql, boolean hasOffset, int _start, int _limit) throws RwlDialectException { 
          
        if(log.isDebugEnabled()) { 
            log.debug(">>RwlDBDialect-start:" + _sql); 
        } 
          
        //add by polarbear , 2009-6-4, 不支持分页的方式 
        if(SQL_SUPPORT_PAGING == 0) { 
            throw new RwlDialectException("Not Support Paging!"); 
        } 
          
        /** 
         * #############Oracle/kingbase分页方式############### 
         */ 
        if(currentDialect == dbtype.oracle || currentDialect == dbtype.kingbase) { 
            _sql = _sql.trim(); 
            boolean isForUpdate = false; 
            if ( _sql.toLowerCase().endsWith(" for update") ) { 
                _sql = _sql.substring( 0, _sql.length()-11 ); 
                isForUpdate = true; 
            } 
              
            StringBuffer pagingSelect = new StringBuffer(_sql.length()+100 ); 
            if (hasOffset) { 
                pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( "); 
            } 
            else { 
                pagingSelect.append("select * from ( "); 
            } 
            pagingSelect.append(_sql); 
            if (hasOffset) { 
                pagingSelect.append(" ) row_ where rownum <= " + (_start + _limit) + ") where rownum_ > " + _start); 
            } 
            else { 
                pagingSelect.append(" ) where rownum <= " + (_start + _limit)); 
            } 
  
            if (isForUpdate) pagingSelect.append(" for update"); 
              
            //结束 
            if(log.isDebugEnabled()) { 
                log.debug(">>RwlDBDialect-end(oracle):" + pagingSelect.toString()); 
            } 
              
              
            return pagingSelect.toString(); 
        } 
        /** 
         * ############## HSQL方式 ############### 
         */ 
        else if(currentDialect == dbtype.hsql) { 
            return new StringBuffer( _sql.length() + 10 ) 
            .append( _sql ) 
            .insert( _sql.toLowerCase().indexOf( "select" ) + 6, hasOffset ? " limit " + _start + " " + _limit : " top "+_start) 
            .toString(); 
        } 
          
        //缺省使用的是mysql的分页方式 
        else if(currentDialect == dbtype.mysql) { 
            String result = new StringBuffer(_sql.length()+20 ) 
            .append(_sql) 
            .append( hasOffset ? " limit " + _start + ", " + _limit : " limit " + _start) 
            .toString(); 
              
            //结束 
            if(log.isDebugEnabled()) { 
                log.debug(">>RwlDBDialect-end(mysql):" + result); 
            } 
              
            return result; 
        } 
          
        /** 
         * ############## SQLServer分页方式 ################ 
         */ 
        else if(currentDialect == dbtype.sqlserver) { 
              
            if(!SQL_SERVER_VERSION.equals("2005")) { 
                throw new RwlDialectException("Not Support Paging!"); 
            } 
              
            StringBuffer pagingBuilder = new StringBuffer();  
            String orderby = getOrderByPart(_sql);  
            String distinctStr = "";  
  
            String loweredString = _sql.toLowerCase();  
            String sqlPartString = _sql.trim();  
            if (loweredString.trim().startsWith("select")) {  
                int index = 6;  
                if (loweredString.startsWith("select distinct")) {  
                    distinctStr = "DISTINCT ";  
                    index = 15;  
                }  
                sqlPartString = sqlPartString.substring(index);  
            }  
            pagingBuilder.append(sqlPartString);  
  
            // if no ORDER BY is specified use fake ORDER BY field to avoid errors  
            if (orderby == null || orderby.length() == 0) {  
                orderby = "ORDER BY CURRENT_TIMESTAMP";  
            }  
  
            StringBuffer result = new StringBuffer();  
            result.append("SELECT * FROM (")   
            .append("SELECT ")  
            .append(distinctStr)  
            .append(" TOP 100 PERCENT ROW_NUMBER() OVER (") //使用TOP 100 PERCENT可以提高性能  
            .append(orderby)  
            .append(") AS __hibernate_row_nr__, ")  
            .append(pagingBuilder)  
            .append(") as ucstarTempTable WHERE __hibernate_row_nr__ >") 
            .append(_start)  
            .append(" AND __hibernate_row_nr__ <=")  
            .append(_start + _limit)  
            .append(" ORDER BY __hibernate_row_nr__");  
              
            //结束 
            if(log.isDebugEnabled()) { 
                log.debug(">>RwlDBDialect-end(sqlserver):" + result.toString()); 
            } 
              
            return result.toString(); 
        } 
          
        //IBM的DB2的分页方式 
        else if(currentDialect == dbtype.db2) { 
            String resultSql = db2Dialect.getLimitString(_sql, _start, _limit); 
            //结束 
            if(log.isDebugEnabled()) { 
                log.debug(">>RwlDBDialect-end(db2):" + resultSql); 
            } 
            return resultSql; 
        } 
          
        /** 
         * ############# 不支持的分页 ############## 
         */ 
        else { 
            log.error("No support Paging!"); 
            return _sql; 
        } 
    } 
      
      
    /** 
     * SQLServer的处理 
     * polarbear 2009-5-9 
     * @param sql 
     * @return 
     */ 
    static String getOrderByPart(String sql) { 
        String loweredString = sql.toLowerCase(); 
        int orderByIndex = loweredString.indexOf("order by"); 
        if (orderByIndex != -1) { 
            // if we find a new "order by" then we need to ignore 
            // the previous one since it was probably used for a subquery 
            return sql.substring(orderByIndex); 
        } else { 
            return ""; 
        } 
    } 
      
    private static boolean hasDistinct(String sql) { 
        return sql.toLowerCase().indexOf("select distinct")>=0; 
    } 
      
    private static String getRowNumber(String sql) { 
        StringBuffer rownumber = new StringBuffer(50) 
            .append("rownumber() over("); 
  
        int orderByIndex = sql.toLowerCase().indexOf("order by"); 
          
        if ( orderByIndex>0 && !hasDistinct(sql) ) { 
            rownumber.append( sql.substring(orderByIndex) ); 
        } 
               
        rownumber.append(") as rownumber_,"); 
          
        return rownumber.toString(); 
    } 
      
    /** 
     * 专门针对DB2处理的SQL代码 
     * polarbear 2009-8-31 
     * @param _sql 
     * @return 
     */ 
    private static String genReturnField(String _sql) { 
        int startOfSelect = _sql.toLowerCase().indexOf("select"); 
        int startOfFrom = _sql.toLowerCase().indexOf("from"); 
        int startOfWhere = _sql.toLowerCase().indexOf("where"); 
        int startOfOrderBy = _sql.toLowerCase().indexOf("order by"); 
        int startOfGroupBy = _sql.toLowerCase().indexOf("group by"); 
          
        String returnField = ""; 
        if(startOfFrom >= 0) { 
            String fromTableStr = ""; 
            if(startOfWhere >= 0) { 
                fromTableStr = _sql.substring(startOfFrom + "from".length(), startOfWhere); 
            } else if(startOfOrderBy >= 0) { 
                fromTableStr = _sql.substring(startOfFrom + "from".length(), startOfOrderBy); 
            } else if(startOfGroupBy >= 0) { 
                fromTableStr = _sql.substring(startOfFrom + "from".length(), startOfGroupBy); 
            } else { 
                fromTableStr = _sql.substring(startOfFrom + "from".length()); 
            } 
            if(fromTableStr.length() > 0) { 
                String[] fromTableStrArr = fromTableStr.split(","); 
                for(String fromTable : fromTableStrArr) { 
                    if(fromTable != null && fromTable.length() > 0) { 
                        String fromTable2 = fromTable.trim(); 
                        int startTableName = fromTable2.indexOf(" "); 
                        String tableNick = ""; 
                        if(startTableName > 0) { 
                            tableNick = fromTable2.substring(startTableName); 
                        } else { 
                            tableNick = fromTable2; 
                        } 
                        tableNick = tableNick.trim(); 
                        returnField += tableNick + ".*" + ","; 
                    } 
                      
                } 
            } 
            if(returnField.length() > 0) { 
                returnField = returnField.substring(0, returnField.length() - 1); 
            } 
              
        } 
          
        if(startOfSelect >= 0 && startOfFrom >= 0) { 
            String selectFromStr = _sql.substring(startOfSelect + "select".length(), startOfFrom); 
            String fromEndStr = _sql.substring(startOfFrom + "from".length(), _sql.length()); 
            selectFromStr = selectFromStr.trim(); 
            if(selectFromStr.length() > 0) { 
                String selectField = ""; 
                String[] tempSqlArr = selectFromStr.split(","); 
                for(String tempStr : tempSqlArr) { 
                    if(tempStr != null && tempStr.length() > 0) { 
                        if(tempStr.equalsIgnoreCase("*")) { 
                            selectField += returnField + ","; 
                        } else { 
                            selectField += tempStr + ","; 
                        } 
                    } 
                } 
                if(selectField.length() > 0) { 
                    selectField = selectField.substring(0,selectField.length() - 1); 
                    return "select" + " " + selectField + " from " + fromEndStr; 
                } 
            } 
        } 
          
        return _sql; 
    } 
      
    /** 
     * 数据库类型 
     * @author polarrwl 
     */ 
    public enum dbtype { 
        oracle, 
        mysql, 
        sqlserver, 
        db2, 
        hsql, 
        kingbase 
    } 
      
    /** 
     * 根据驱动得到对应的数据库类型 
     * @param _driver 
     * @return 
     */ 
    public static dbtype getDbtypeByDriver(String _driver) { 
        if(_driver != null) { 
            if(_driver.toLowerCase().indexOf("oracle") >= 0) { 
                return dbtype.oracle; 
            } else if(_driver.toLowerCase().indexOf("kingbase") >= 0) { 
                return dbtype.kingbase; 
            } else if(_driver.toLowerCase().indexOf("mysql") >= 0) { 
                return dbtype.mysql; 
            } else if(_driver.toLowerCase().indexOf("sqlserver") >= 0) { 
                return dbtype.sqlserver; 
            } else if(_driver.toLowerCase().indexOf("hsql") >= 0) { 
                return dbtype.hsql; 
            } else if(_driver.toLowerCase().indexOf("db2") >= 0) { 
                return dbtype.db2; 
            } 
        } 
        return null; 
    } 
      
    /** 
     * 设定当前的数据库类型 
     * @param _dbtype 
     */ 
    public void setCurrentDialect(dbtype _dbtype) { 
          
        log.info("设定当前的数据库类型(currentDialect):" + _dbtype); 
          
        if(_dbtype != null) { 
            currentDialect = _dbtype; 
        } 
    } 
      
    public static void main(String[] args) { 
        System.out.println(genReturnField("select * from user order by type")); 
    } 
}

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/10543.html

(0)
上一篇 2021年7月19日 10:19
下一篇 2021年7月19日 10:19

相关推荐

发表回复

登录后才能评论