/** * Copyright (c) 2004-2011 Wang Jinbao(Julian Wong), http://www.ralasafe.com * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php */ package org.ralasafe.db.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.ralasafe.ObjectNewer; import org.ralasafe.db.Column; import org.ralasafe.db.ColumnAdapter; import org.ralasafe.db.DBLevelException; import org.ralasafe.db.DBPower; import org.ralasafe.db.GroupPart; import org.ralasafe.db.OrderPart; import org.ralasafe.db.SelectCondition; import org.ralasafe.db.SelectConditionUtil; import org.ralasafe.db.Table; import org.ralasafe.db.TableSelector; import org.ralasafe.db.WhereElement; import org.ralasafe.db.WhereElementUtil; import org.ralasafe.util.DBUtil; import org.ralasafe.util.StringUtil; /** * WARNING!!!! * We will deprecate it later. */ public class TableSelectorImpl implements TableSelector { private ObjectNewer objectNewer; private String selectByIdSql; private String selectByUniqueSql; private String selectSqlWithoutWherePart; private String selectCountByIdSql; private String selectCountByUniqueSql; private Table table; private static Log logger = LogFactory.getLog( TableSelectorImpl.class ); public Table getTable() { return table; } public void setTable( Table table ) { this.table=table; SelectCondition byIdCdtn=SelectConditionUtil.simplyConnectColumns( table.getIdColumns() ); SelectCondition byUniqueCdtn=SelectConditionUtil.simplyConnectColumns( table.getUniqueColumns() ); selectSqlWithoutWherePart=DBUtil.selectSql( table.getName(), table.getColumnNames() ); if( byIdCdtn!=null ) { String sql=WhereElementUtil.toSql( byIdCdtn ); selectByIdSql=selectSqlWithoutWherePart + sql; selectCountByIdSql="select count(1) from " + table.getName() + sql; } if( byUniqueCdtn!=null ) { String sql=WhereElementUtil.toSql( byUniqueCdtn ); selectByUniqueSql=selectSqlWithoutWherePart + sql; selectCountByUniqueSql="select count(1) from " + table.getName() + sql; } } public TableSelectorImpl() { } public void setObjectNewer( ObjectNewer objectNewer ) { this.objectNewer=objectNewer; } public Collection select( SelectCondition cdtn, Object o ) throws DBLevelException { Connection conn=null; try { conn=DBPower.getConnection( table.getId() ); return select( conn, cdtn, o ); } finally { DBUtil.close( conn ); } } public Object selectByIdColumns( Object o ) throws DBLevelException { Connection conn=null; try { conn=DBPower.getConnection( table.getId() ); return selectByIdColumns( conn, o ); } finally { DBUtil.close( conn ); } } public Object selectByUniqueColumns( Object o ) throws DBLevelException { Connection conn=null; try { conn=DBPower.getConnection( table.getId() ); return selectByUniqueColumns( conn, o ); } finally { DBUtil.close( conn ); } } public Collection select( Connection conn, SelectCondition cdtn, Object o ) throws DBLevelException { String selectSql=selectSqlWithoutWherePart + WhereElementUtil.toSql( cdtn ); return select( conn, selectSql, cdtn, o ); } public Collection selectByPage( SelectCondition cdtn, Object o, int fromIndex, int pageSize ) throws DBLevelException { Connection conn=null; try { conn=DBPower.getConnection( table.getId() ); return selectByPage( conn, cdtn, o, fromIndex, pageSize ); } finally { DBUtil.close( conn ); } } public Collection selectByPage( Connection conn, SelectCondition cdtn, Object o, int fromIndex, int pageSize ) throws DBLevelException { String selectSql=""; String dbName; try { dbName=conn.getMetaData().getDatabaseProductName(); dbName=dbName.toUpperCase(); } catch( SQLException e ) { logger.error( "", e ); throw new DBLevelException( e ); } if( dbName.indexOf( "MYSQL" )!=-1 ) { //SQL:select .. from .. order by .. limit ?,? selectSql=selectSqlWithoutWherePart + WhereElementUtil.toSql( cdtn ) + " limit " + (fromIndex-1) + "," + pageSize; } else if( dbName.indexOf( "ORACLE" )!=-1 ) { StringBuffer buff=new StringBuffer(); buff.append( "SELECT " ); StringUtil.append( buff, table.getColumnNames() ); buff.append( " FROM (" ); buff.append( "select *, rownum as __rn from (" ) .append( selectSqlWithoutWherePart ) .append( WhereElementUtil.toSql( cdtn ) ) .append( ") where __rn<=" +(fromIndex+pageSize-1) ) .append( ") where __rn>=" + fromIndex ); selectSql=buff.toString(); } else if( dbName.indexOf( "DB2" )!=-1 ) { //SQL LOOKS LIKE //select * from ( //SELECT rownumber() //over(ORDER BY SCORE DESC) //as row_, * FROM STUDENT ORDER BY SCORE DESC ) //as temp_ where row_ between 11 and 20 StringBuffer buff=new StringBuffer(); buff.append( "SELECT " ); StringUtil.append( buff, table.getColumnNames() ); buff.append( " FROM (" ); buff.append( "SELECT " ); StringUtil.append( buff, table.getColumnNames() ); buff.append( ",rownumber() over(" ); append( buff, cdtn.getOrderPart() ); buff.append( ") as __rn FROM " ) .append( table.getName() ); append( buff, cdtn.getOrderPart() ); append( buff, cdtn.getGroupPart() ); buff.append( ") as temp_ where __rn between " ) .append( fromIndex ) .append( " and " ) .append( fromIndex+pageSize-1 ); selectSql=buff.toString(); } if( logger.isDebugEnabled() ) { logger.debug( selectSql ); } if( dbName.indexOf( "MYSQL" )!=-1 || dbName.indexOf( "ORACLE" )!=-1 || dbName.indexOf( "DB2" )!=-1 ) { return select( conn, selectSql, cdtn, o ); } else { return select( conn, selectSql, cdtn, o, fromIndex, pageSize ); } } private static void append( StringBuffer buff, GroupPart groupPart ) { if( groupPart==null||groupPart.getColumnNames().length==0 ) return; String[] columnNames=groupPart.getColumnNames(); buff.append( " group by " ); for( int i = 0; i < columnNames.length; i++ ) { if( i!=0 ) { buff.append( "," ); } buff.append( columnNames[i] ); } } private static void append( StringBuffer buff, OrderPart orderPart ) { if( orderPart==null||orderPart.getColumnNames().length==0 ) return; String[] columnNames=orderPart.getColumnNames(); String[] orderTypes=orderPart.getOrderTypes(); buff.append( " ORDER BY " ); for( int i=0; i<columnNames.length; i++ ) { if( i!=0 ) { buff.append( "," ); } buff.append( columnNames[i] ); if( orderTypes!=null && "DESC".equalsIgnoreCase( orderTypes[i] ) ) { buff.append( " DESC" ); } } } public Object selectByIdColumns( Connection conn, Object o ) throws DBLevelException { Collection collection=select( conn, selectByIdSql, table.getIdColumns(), o ); if( collection.size()>0 ) { return collection.iterator().next(); } else { return null; } } public Object selectByUniqueColumns( Connection conn, Object o ) throws DBLevelException { Collection collection=select( conn, selectByUniqueSql, table.getUniqueColumns(), o ); if( collection.size()>0 ) { return collection.iterator().next(); } else { return null; } } private Collection select( Connection conn, String pstmtSql, SelectCondition cdtn, Object o ) throws DBLevelException { List selectByColumns=new LinkedList(); List hints=new LinkedList(); WhereElement whereElement=null; if( cdtn!=null ) { whereElement=cdtn.getWhereElement(); } WhereElementUtil.extractColumns( whereElement, selectByColumns, o, hints ); return select( conn, pstmtSql, selectByColumns, hints ); } private Collection select( Connection conn, String pstmtSql, SelectCondition cdtn, Object o, int startIndex, int pageSize ) throws DBLevelException { List selectByColumns=new LinkedList(); List hints=new LinkedList(); WhereElementUtil.extractColumns( cdtn==null?null:cdtn.getWhereElement(), selectByColumns, o, hints ); return select( conn, pstmtSql, selectByColumns, hints, startIndex, pageSize ); } private Collection select( Connection conn, String pstmtSql, List selectByColumns, List hints ) throws DBLevelException { List result=new LinkedList(); PreparedStatement pstmt=null; ResultSet rs=null; try { pstmt=conn.prepareStatement( pstmtSql ); if( selectByColumns!=null ) { Iterator columnIter=selectByColumns.iterator(); Iterator hintsIter=hints.iterator(); int i=1; while( columnIter.hasNext() ) { Column column=(Column) columnIter.next(); ColumnAdapter adapter=column.getAdapter(); adapter.setPreparedStatement( pstmt, i, hintsIter.next() ); i++; } } rs=pstmt.executeQuery(); while( rs.next() ) { Object obj=objectNewer.newObject(); Column[] columns=table.getColumns(); for( int i=0; i<columns.length; i++ ) { Column column=columns[i]; column.getAdapter().readResultSet( rs, i+1, obj ); } result.add( obj ); } } catch( SQLException e ) { logger.error( "", e ); throw new DBLevelException( e ); } finally { DBUtil.close(rs); DBUtil.close( pstmt ); } return result; } private Collection select( Connection conn, String pstmtSql, List selectByColumns, List hints, int startIndex, int pageSize ) throws DBLevelException { List result=new LinkedList(); PreparedStatement pstmt=null; ResultSet rs=null; try { pstmt=conn.prepareStatement( pstmtSql ); if( selectByColumns!=null ) { Iterator columnIter=selectByColumns.iterator(); Iterator hintsIter=hints.iterator(); int i=1; while( columnIter.hasNext() ) { Column column=(Column) columnIter.next(); ColumnAdapter adapter=column.getAdapter(); adapter.setPreparedStatement( pstmt, i, hintsIter.next() ); i++; } } rs=pstmt.executeQuery(); int index=1; while( index<startIndex&&rs.next() ) { index++; } int readSize=0; while( rs.next() && readSize<pageSize ) { Object obj=objectNewer.newObject(); Column[] columns=table.getColumns(); for( int i=0; i<columns.length; i++ ) { Column column=columns[i]; column.getAdapter().readResultSet( rs, i+1, obj ); } result.add( obj ); readSize++; } } catch( SQLException e ) { logger.error( "", e ); throw new DBLevelException( e ); } finally { DBUtil.close(rs); DBUtil.close( pstmt ); } return result; } private Collection select( Connection conn, String pstmtSql, Column[] selectByColumns, Object o ) throws DBLevelException { List result=new LinkedList(); PreparedStatement pstmt=null; ResultSet rs=null; try { pstmt=conn.prepareStatement( pstmtSql ); if( selectByColumns!=null ) { for( int i=0; i<selectByColumns.length; i++ ) { ColumnAdapter adapter=selectByColumns[i].getAdapter(); adapter.setPreparedStatement( pstmt, i+1, o ); } } rs=pstmt.executeQuery(); while( rs.next() ) { Object obj=objectNewer.newObject(); Column[] columns=table.getColumns(); for( int i=0; i<columns.length; i++ ) { Column column=columns[i]; column.getAdapter().readResultSet( rs, i+1, obj ); } result.add( obj ); } } catch( SQLException e ) { logger.error( "", e ); throw new DBLevelException( e ); } finally { DBUtil.close(rs); DBUtil.close( pstmt ); } return result; } public int selectCount( SelectCondition cdtn, Object o ) { Connection conn=null; try { conn=DBPower.getConnection( table.getId() ); return selectCount( conn, cdtn, o ); } finally { DBUtil.close( conn ); } } public int selectCount( Connection conn, SelectCondition cdtn, Object o ) { String sql="select count(1) from " + table.getName() + WhereElementUtil.toSql( cdtn ); return selectCount( conn, sql, cdtn, o ); } public boolean isExistByIdColumns( Object o ) { Connection conn=null; try { conn=DBPower.getConnection( table.getId() ); return isExistByIdColumns( conn, o ); } finally { DBUtil.close( conn ); } } public boolean isExistByUniqueColumns( Object o ) { Connection conn=null; try { conn=DBPower.getConnection( table.getId() ); return isExistByUniqueColumns( conn, o ); } finally { DBUtil.close( conn ); } } public boolean isExistByUniqueColumns( Connection conn, Object o ) { int selectCount=selectCount( conn, selectCountByUniqueSql, table.getUniqueColumns(), o ); return selectCount>0 ? true: false; } public boolean isExistByIdColumns( Connection conn, Object o ) { int selectCount=selectCount( conn, selectCountByIdSql, table.getIdColumns(), o ); return selectCount>0 ? true: false; } private int selectCount( Connection conn, String sql, SelectCondition cdtn, Object o ) throws DBLevelException { List selectByColumns=new LinkedList(); List hints=new LinkedList(); WhereElementUtil.extractColumns( cdtn==null?null:cdtn.getWhereElement(), selectByColumns, o, hints ); return selectCount( conn, sql, selectByColumns, hints ); } private int selectCount( Connection conn, String sql, List selectByColumns, List hints ) throws DBLevelException { PreparedStatement pstmt=null; ResultSet rs=null; try { pstmt=conn.prepareStatement( sql ); if( selectByColumns!=null ) { Iterator columnIter=selectByColumns.iterator(); Iterator hintsIter=hints.iterator(); int i=1; while( columnIter.hasNext() ) { Column column=(Column) columnIter.next(); ColumnAdapter adapter=column.getAdapter(); adapter.setPreparedStatement( pstmt, i, hintsIter.next() ); i++; } } rs=pstmt.executeQuery(); if( rs.next() ) { return rs.getInt( 1 ); } else { return 0; } } catch( SQLException e ) { logger.error( "", e ); throw new DBLevelException( e ); } finally { DBUtil.close(rs); DBUtil.close( pstmt ); } } private int selectCount( Connection conn, String sql, Column[] selectByColumns, Object o ) throws DBLevelException { PreparedStatement pstmt=null; ResultSet rs=null; try { pstmt=conn.prepareStatement( sql ); if( selectByColumns!=null ) { for( int i=0; i<selectByColumns.length; i++ ) { ColumnAdapter adapter=selectByColumns[i].getAdapter(); adapter.setPreparedStatement( pstmt, i+1, o ); } } rs=pstmt.executeQuery(); if( rs.next() ) { return rs.getInt( 1 ); } else { return 0; } } catch( SQLException e ) { logger.error( "", e ); throw new DBLevelException( e ); } finally { DBUtil.close(rs); DBUtil.close( pstmt ); } } }