曾经,为了避免“Access restriction” ,打算自动实现一个CachedRowSet ,于是新建一个类implements CachedRowSet , 没有做其它任何工作,代码已经2千多行了, class文件38K !!!
所以多次因此放弃了。
今天想到用动态代理实现CachedRowSet ,于是只实现其中部分有用的方法,剩余的300多个无用方法不处理。几百行代码就解决问题 ,并且
支持修改结果集内容,增加结果集的列,
getXXX( ) 不会字字段不存在出现讨厌的SQLException
不会因字段使用了别名出现字段不存在的问题
调用方式
ProxyHandler
SimpleCachedRowSetImpl
余下程序见附件
已有 0人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐
所以多次因此放弃了。
今天想到用动态代理实现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(); } }
余下程序见附件
- 本文附件下载:
- SimpleCachedRowSet.7z (4.9 KB)
已有 0人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐