動的エージェントを使用して簡素化版CachedRowSetImplを実現する。
14138 ワード
かつては、「Access restication」を避けるために、CachedRowSetを自動的に実現しようとしていました。 ,そこで、新しいクラスのimplemens CachedRowSetを作って、他の仕事をしていません。コードはもう2千行以上になりました。クラスファイル38 K!
だから何度も諦めました。
今日は動的エージェントでCachedRowSetを実現したいと思います。その中の部分的に有用な方法だけを実現して、残りの300以上の無駄な方法は処理しません。何百行のコードで問題を解決します。
修正結果セットの内容をサポートし、結果セットの列を追加します。
get XXX()は文字フィールドが存在しません。嫌なSQLExceptionが現れません。
フィールドにエイリアスを使ってフィールドが存在しない問題はありません。
呼び出し方式
だから何度も諦めました。
今日は動的エージェントでCachedRowSetを実現したいと思います。その中の部分的に有用な方法だけを実現して、残りの300以上の無駄な方法は処理しません。何百行のコードで問題を解決します。
修正結果セットの内容をサポートし、結果セットの列を追加します。
get XXX()は文字フィールドが存在しません。嫌なSQLExceptionが現れません。
フィールドにエイリアスを使ってフィールドが存在しない問題はありません。
呼び出し方式
ResultSet rs = statement.executeQuery(sql);
CachedRowSet rowSet = SimpleCachedRowSetImpl.newInstance();
rowSet.populate( rs );
ProxyHandlerpublic class ProxyHandler implements InvocationHandler {
private Object concreteClass;
public ProxyHandler(Object concreteClass) {
this.concreteClass = concreteClass;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try{
method = concreteClass.getClass().getMethod(method.getName(), method.getParameterTypes() );
Object object = method.invoke(concreteClass, args);// Java ,
return object;
}catch(NoSuchMethodException ex){
if( method.getName().startsWith("set")){
throw new NoSuchMethodException( ex.getMessage() +", setObject");
}
throw ex;
}catch( InvocationTargetException ex){
// stacktrace
throw ex.getCause();
}
}
}
SimpleCachedRowSetImpl
public class SimpleCachedRowSetImpl implements SimpleRowSet {
LinkedList<Object[]> data = new LinkedList<Object[]>();
TreeMap<String,Integer > fieldNameMap = new TreeMap<String,Integer >( String.CASE_INSENSITIVE_ORDER );
private static final int FETCHCOUNT = 2000;
private int cursor =-1;
private int rowCount =0;
private int pageSize = 0;
private int columnCount =0;
private ResultSetMetaData meta;
private SimpleCachedRowSetImpl(){}
/**
* CachedRowSet
* @return
*/
public static CachedRowSet newInstance() {
SimpleCachedRowSetImpl rowset = new SimpleCachedRowSetImpl() ;
InvocationHandler ih = new ProxyHandler( rowset );
Class<?>[] interfaces = {CachedRowSet.class,SimpleRowSet.class};
Object newProxyInstance = Proxy.newProxyInstance( SimpleCachedRowSetImpl.class.getClassLoader() , interfaces, ih);
return (CachedRowSet)newProxyInstance;
}
private void updateMeta(ResultSet rs) throws SQLException{
ResultSetMetaData oldmeta = rs.getMetaData();
ResultSetMeta meta = new ResultSetMeta(oldmeta);
columnCount = oldmeta.getColumnCount();
for(int i=1;i<=columnCount;i++){
Field field = new Field();
field.catalogName = oldmeta.getCatalogName( i );
field.columnClassName = oldmeta.getColumnClassName( i );
field.columnType = oldmeta.getColumnType( i );
field.columnLabel = oldmeta.getColumnLabel( i );
field.columnName = oldmeta.getColumnName( i );
field.precision = oldmeta.getPrecision( i );
field.scale = oldmeta.getScale( i );
field.schemaName = oldmeta.getSchemaName( i );
field.table = oldmeta.getTableName( i );
meta.addField(field);
}
this.meta = meta;
}
public void populate(ResultSet rs, int start) throws SQLException {
if( start>-1){
rs.absolute(start);
rs.setFetchSize( this.pageSize );
}else{
rs.setFetchSize( FETCHCOUNT );
}
updateMeta(rs);
rowCount = 0;
while(rs.next()){
Object[] row = new Object[ columnCount ];
for(int i=1;i<=columnCount ;i++ ){
row[ i-1 ] = rs.getObject( i );
}
data.add( row );
rowCount++;
if(start>-1 && rowCount> pageSize)
break;
}
//
for(int i=1;i<=columnCount;i++){
String fieldName = meta.getColumnLabel( i ); // as
fieldNameMap.put( fieldName , i -1 ); // 0
}
rowCount = data.size();
}
public void populate(ResultSet rs ) throws SQLException {
populate( rs , -1 );
}
@Override
public boolean next() throws SQLException{
if( cursor<rowCount-1){
cursor++;
return true;
}
cursor = rowCount;
return false;
}
@Override
public void beforeFirst() throws SQLException{
cursor=-1;
}
@Override
public String getString(String key ) throws SQLException{
Object value = getObject( key );
if( value==null)
return null;
return value.toString();
}
@Override
public String getString(int index ) throws SQLException{
Object value = getObject( index );
if( value==null)
return null;
return value.toString();
}
@Override
public Object getObject(String key ) throws SQLException{
int index = getIndex(key);
return getObject(index );
}
@Override
public Object getObject(int index ) throws SQLException{
if( index==-1)
return null;
if( index<1 || index> columnCount ){
throw new SQLException(" 1-"+columnCount + " " );
}
Object[] row = data.get( cursor );
Object value = row[ index -1 ];
return value;
}
@Override
public int getInt(int index) throws SQLException {
Object value = getObject(index);
if(value==null)
return 0 ;
if( value instanceof Number ){
return ((Number)value).intValue();
}
if( value instanceof BigDecimal ){
return ((BigDecimal)value).intValue();
}
String svalue = value.toString();
try{
return Integer.parseInt( svalue );
}catch(NumberFormatException ex){
throw new SQLException(svalue+" int ");
}
}
@Override
public int getInt(String key) throws SQLException {
int index = getIndex(key);
return getInt( index );
}
@Override
public long getLong(int index ) throws SQLException {
Object value = getObject(index);
if(value==null)
return 0 ;
if( value instanceof Number ){
return ((Number)value).longValue();
}
if( value instanceof BigDecimal ){
return ((BigDecimal)value).longValue();
}
String svalue = value.toString();
try{
return Long.parseLong( svalue );
}catch(NumberFormatException ex){
throw new SQLException(svalue+" long ");
}
}
@Override
public long getLong(String key) throws SQLException {
int index = getIndex( key );
return getLong( index );
}
@Override
public float getFloat(String key) throws SQLException {
int index = getIndex( key );
return getFloat( index );
}
@Override
public float getFloat(int index) throws SQLException {
Object value = getObject(index);
if(value==null)
return 0 ;
if( value instanceof Number ){
return ((Number)value).floatValue();
}
if( value instanceof BigDecimal ){
return ((BigDecimal)value).floatValue();
}
String svalue = value.toString();
try{
return Float.parseFloat( svalue );
}catch(NumberFormatException ex){
throw new SQLException(svalue+" float ");
}
}
@Override
public BigDecimal getBigDecimal(int index) throws SQLException {
Object value = getObject(index);
if(value==null)
return null ;
return ((BigDecimal)value) ;
}
@Override
public BigDecimal getBigDecimal(String key) throws SQLException {
int index = getIndex( key );
return getBigDecimal( index );
}
@Override
public double getDouble(int index) throws SQLException {
Object value = getObject(index);
if(value==null)
return 0 ;
if( value instanceof Number ){
return ((Number)value).doubleValue();
}
if( value instanceof BigDecimal ){
return ((BigDecimal)value).doubleValue();
}
String svalue = value.toString();
try{
return Double.parseDouble( svalue );
}catch(NumberFormatException ex){
throw new SQLException(svalue+" double ");
}
}
@Override
public double getDouble(String key) throws SQLException {
int index = getIndex( key );
return getDouble( index );
}
// @Override
// public Date getDate(String key) throws SQLException {
// int index = getIndex( key );
// return getDate( index );
//
// }
private int getIndex(String key){
Integer index = fieldNameMap.get(key);
if( index==null)
return -1;
return index +1;
}
// @Override
// public Date getDate(int index) throws SQLException {
//
// Object value = getObject(index );
// if(value==null)
// return null ;
// if( value instanceof Date ){
// return ((Date)value);
// }
// throw new NotImplementedException();
//
// }
//
// @Override
// public Date getDate(int index, Calendar calendar) throws SQLException {
// throw new NotImplementedException();
//
// }
//
// @Override
// public Date getDate(String fieldName, Calendar calendar) throws SQLException {
// throw new NotImplementedException();
//
// }
//
// @Override
// public Time getTime(int index) throws SQLException {
// throw new NotImplementedException();
//
// }
//
// @Override
// public Time getTime(String fieldName) throws SQLException {
// throw new NotImplementedException();
//
// }
//
// @Override
// public Time getTime(int index, Calendar calendar) throws SQLException {
// throw new NotImplementedException();
//
// }
//
// @Override
// public Time getTime(String fieldName, Calendar calendar) throws SQLException {
// throw new NotImplementedException();
//
// }
@Override
public Timestamp getTimestamp(int index) throws SQLException {
Object value = getObject(index );
int type = meta.getColumnType( index );
if( type== Types.TIMESTAMP ){
return ((Timestamp)value);
}
throw new NotImplementedException();
}
@Override
public Timestamp getTimestamp(String fieldName) throws SQLException {
return getTimestamp( getIndex( fieldName ));
}
// @Override
// public Timestamp getTimestamp(int index, Calendar calendar) throws SQLException {
//
// throw new NotImplementedException();
//
// }
//
// @Override
// public Timestamp getTimestamp(String fieldName, Calendar calendar) throws SQLException {
// throw new NotImplementedException();
//
// }
// @Override
// public Blob getBlob(String fieldName) throws SQLException {
// throw new NotImplementedException();
//
// }
@Override
public boolean getBoolean(int index) throws SQLException {
Object val = getObject(index);
return new Integer(1).equals(val);
}
@Override
public boolean getBoolean(String key) throws SQLException {
Object val = getObject( key );
return new Integer(1).equals(val);
}
@Override
public byte getByte(int index) throws SQLException {
Object val = getObject( index );
if( val==null)
return 0;
return (Byte)val;
}
@Override
public byte getByte(String key) throws SQLException {
Object val = getObject( key );
if( val==null)
return 0;
return (Byte)val;
}
// @Override
// public byte[] getBytes(int index) throws SQLException {
// Object val = getObject( index );
// if( val==null)
// return null;
// return (byte[])val;
//
// }
//
// @Override
// public byte[] getBytes(String fieldName) throws SQLException {
// return getBytes( getIndex(fieldName));
//
// }
public void setPageSize( int pageSize ) throws SQLException{
this.pageSize = pageSize;
}
@Override
public ResultSetMetaData getMetaData() throws SQLException {
return meta;
}
@Override
public void setObject(int colIndex, Object value) throws SQLException {
if( colIndex<1){
throw new SQLException(" 1 ");
}
Object[] row = getCurrentRow();
if( colIndex>row.length){
row =Arrays.copyOf( row , colIndex );
data.add( cursor , row );
}
row[ colIndex -1 ] = value;
}
private Object[] getCurrentRow() {
return data.get( cursor );
}
@Override
public void setObject(String field, Object value) throws SQLException {
int index = getIndex( field );
if( index==-1){
addColumn( field );
index = getIndex( field );
}
//Object[] row = getCurrentRow();
setObject( index , value );
}
private void addColumn(String field) {
fieldNameMap.put( field , fieldNameMap.size() );
columnCount = fieldNameMap.size();
}
}
残りの手続きは添付ファイルを参照してください。