一個針對不同數據庫的分頁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"));
}
}</pre>