- 浏览: 8783 次
- 来自: ...
最新评论
使用动态代理实现精简版CachedRowSetImpl
曾经,为了避免“Access restriction” ,打算自动实现一个CachedRowSet ,于是新建一个类implements CachedRowSet , 没有做其它任何工作,代码已经2千多行了, class文件38K !!!
所以多次因此放弃了。
今天想到用动态代理实现CachedRowSet ,于是只实现其中部分有用的方法,剩余的300多个无用方法不处理。几百行代码就解决问题 ,并且
支持修改结果集内容,增加结果集的列,
getXXX( ) 不会字字段不存在出现讨厌的SQLException
不会因字段使用了别名出现字段不存在的问题
调用方式
ProxyHandler
SimpleCachedRowSetImpl
余下程序见附件
所以多次因此放弃了。
今天想到用动态代理实现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)
- 下载次数: 8
相关推荐
在精简版中,VB6.0的窗体设计工具依然可用,开发者可以轻松创建各种用户界面,包括菜单、按钮、文本框、列表框等控件,通过设置控件属性和编写事件处理代码,实现交互式的应用程序。此外,VB6.0的集成开发环境(IDE...
标题中的"超级精简版的jre"指的是对标准JRE进行优化和裁剪,移除了不必要的组件和服务,以实现更小的体积、更快的启动速度以及更低的资源消耗。 精简版JRE通常是为了满足特定应用场景的需求,比如嵌入式设备、低...
【Matlab精简版】是针对那些只需要使用Matlab基础功能的用户设计的,它相比标准版具有更小的体积,降低了对系统资源的占用,是轻量级的计算工具。Matlab是一款强大的数学计算软件,广泛应用于工程计算、数据分析、...
精简版则意味着在保留核心功能的同时,去除了不必要的组件,以实现更小的体积和更快的启动速度。 在使用CAJViewer绿色精简版时,用户需确保自己的电脑系统环境满足软件运行的基本要求,例如兼容的操作系统版本和...
在实际应用中,Borland 3.1精简版的使用步骤大致如下: 1. 创建项目:利用IDE创建一个新的工程,设置好编译选项,包括目标架构和优化级别。 2. 添加源代码:将uCOSII的源代码添加到项目中,这通常包括内核文件、任务...
1. **体积减小**:原版Windows XP的安装文件通常在650MB以上,而超级精简版将其压缩至98MB,通过删除非必要的组件和服务实现了大幅瘦身。 2. **启动快速**:由于系统组件减少,启动时间显著缩短,对于需要快速启动的...
此外,出于安全考虑,不建议在生产环境中直接使用未授权的精简版系统镜像,而是应该选择官方渠道获取授权的完整版系统,以确保系统更新和安全性。 总的来说,"Win2003精简版.7z"是一个便于学习和测试的Windows ...
BORLAND3.1精简版使用流程,安装教程进行设置,就会轻松实用BORLAND3.1精简版了
使用时,用户可以通过SQL Server Management Studio Express(或其精简版)进行数据库的管理和操作。 总的来说,SQL Server 2000 精简版虽然功能有所缩减,但仍然提供了可靠且基础的数据库服务,是初学者和小型企业...
4. **数据链接**:Visio 2003支持数据链接功能,可以将图表与外部数据源(如数据库或Excel表格)关联,实时更新图表信息,实现动态可视化。 5. **智能图表**:具备自动布局和连接线调整功能,能帮助用户更高效地...
MySQL5.7精简版是一款轻量级但功能强大的关系型数据库管理系统,它在MySQL5.7的基础上进行了优化,去除了部分非核心组件,以适应更广泛的使用场景,特别是对于那些对系统资源有限制或者不需要全部功能的用户。...
**PADS 9.5三合一精简版详解** PADS(PowerPCB)是一款广泛应用于电子设计自动化领域的软件,由 Mentor Graphics 公司开发,主要用于电路板设计、布局布线以及PCB(印刷电路板)设计。在这个特定的版本——"PADS ...
标题中的“PADS9.3精简版100多M”指的是PADS Logic, Layout,和PCB Router三合一的精简版本,这是一款强大的电子设计...通过阅读提供的文本文件,用户可以了解如何正确安装和使用这个精简版软件,进一步提高设计效率。
jquery 精简版 jquery 精简版 jquery 精简版jquery 精简版 jquery 精简版 jquery 精简版 jquery 精简版
- 开发者测试环境:开发者在调试和测试Java桌面应用时,若不需要开发工具,使用此精简版JRE足够。 - 教学环境:对于初学者,无需安装庞大的Java开发工具包(JDK),仅安装这个JRE即可运行学习项目。 - 低配置设备...
标题 "AD6 精简版 免安装" 指的是Altium Designer的一个特别版本,这个版本经过了优化和裁剪,目的是提供一个轻量级的解决方案,无需正式安装即可使用。AD6,全称Altium Designer 6,是一款业界广泛使用的电子设计...
这个"SQL Server 2000 SP4企业版精简版8M.rar"是一个压缩包,其中包含了SQL Server 2000的企业版精简版安装程序——"SQL Server 2000 SP4企业版精简版8M.exe"。"SP4"指的是Service Pack 4,这是SQL Server 2000的...
"VB精简版 免安装"通常指的是一个经过优化、体积较小的版本,它无需进行完整的安装过程,可以直接运行,方便用户快速使用或在有限的系统资源下操作。 在VB精简版中,微软可能移除了部分非核心功能,例如某些高级的...