使用动态代理实现精简版CachedRowSetImpl

曾经,为了避免“Access restriction” ,打算自动实现一个CachedRowSet ,于是新建一个类implements CachedRowSet , 没有做其它任何工作,代码已经2千多行了, class文件38K !!!
所以多次因此放弃了。

今天想到用动态代理实现CachedRowSet ,于是只实现其中部分有用的方法,剩余的300多个无用方法不处理。几百行代码就解决问题 ,并且
支持修改结果集内容,增加结果集的列,
getXXX( ) 不会字字段不存在出现讨厌的SQLException
不会因字段使用了别名出现字段不存在的问题

调用方式


ResultSet rs = statement.executeQuery(sql);
CachedRowSet rowSet = SimpleCachedRowSetImpl.newInstance();
rowSet.populate( rs );

ProxyHandler
public    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();

}



}


余下程序见附件
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值