将CachedRowSet中的数据转储到对象中

虽然还有很多bug,但凑合能用,就是将CachedRowSet中的数据转换成对象或List。省去了繁琐难看的一系列get/set方法。

先说调用:

注:

cachedRowSet是查询的结果集

Student是对应于Student表的实体类

1. 从数据库Student表中查询出多行数据,要将其存入ArrayList<Student>中:

ArrayList<Student> student = Convert.RStoList(cachedRowSet , Student.class ) ;

2. 从数据库Student表中查询出单行数据,并将其存入Student对象中:

cachedRowSet.next() ;

Student student = Convert.RStoObject(cachedRowSet , Student.class) ;

  1 package util;
  2
  3 import java.lang.reflect.InvocationTargetException;
  4 import java.lang.reflect.Method;
  5 import java.sql.ResultSetMetaData;
  6 import java.sql.SQLException;
  7 import java.text.ParseException;
  8 import java.text.SimpleDateFormat;
  9 import java.util.ArrayList;
 10 import java.util.Date;
 11
 12 import javax.sql.rowset.CachedRowSet;
 13
 14 import com.sun.rowset.CachedRowSetImpl;
 15
 16 /**
 17  *
 18  * @author caiyao
 19  *
 20  * @function 类型转换
 21  */
 22 public class Convert {
 23     /**
 24      * 将CachedRowSetImpl中的多条记录存储进List中
 25      * @param cachedRS CachedRowSetImpl结果集
 26      * @param c List中元素类型
 27      * @return ArrayList对象
 28      * @throws SQLException  cachedRS.next()导致的异常
 29      * @throws RuntimeException
 30      * @throws InvocationTargetException
 31      * @throws ClassNotFoundException
 32      * @throws NoSuchMethodException
 33      * @throws IllegalAccessException
 34      * @throws InstantiationException
 35      */
 36     public static <T> ArrayList<T> RStoList(CachedRowSet cachedRS , Class<T> c)
 37             throws SQLException, InstantiationException, IllegalAccessException,
 38             NoSuchMethodException, ClassNotFoundException, InvocationTargetException,
 39             RuntimeException{
 40         ArrayList<T> store = new ArrayList<T>() ;
 41         while(cachedRS.next()){
 42             T object = RStoObject(cachedRS , c ) ;
 43             store.add(object) ;
 44         }
 45         return store ;
 46     }
 47
 48     /**
 49      * 将ResultSet类型的结果集转换成Object类型的对象
 50      *  注:
 51      * 1. 该方法只能转换只有一条结果的CachedRowSet。
 52      * 2.rs结果集中得到的值xxx,在类中要有相应的setXxx方法
 53      *
 54      * @param rs
 55      *            结果集
 56      * @param c
 57      *            Class类型的值,可以通过Class.forName(类名)获取,要确定该类有无参的构造方法,
 58      *            否则会出现InstantiationException异常
 59      * @return 转换之后的对象
 60      * @throws InstantiationException
 61      * @throws IllegalAccessException
 62      * @throws SQLException
 63      * @throws RuntimeException
 64      * @throws NoSuchMethodException
 65      * @throws ClassNotFoundException
 66      * @throws InvocationTargetException
 67      *             注:
 68      *                1. 该方法只能转换只有一条结果的CachedRowSet。
 69      *                2.rs结果集中得到的值xxx,在类中要有相应的setXxx方法
 70      *             3. 在单独调用这个方法的时候(不是通过RStoList的间接调用)。
 71      *             需要在传递CachedRowSet这个参数之前调用rs的next()方法。否则会出现指针无效的错误
 72      *             4. 使用该方法将结果集中的数据转储到对象中时,要对象中属性get/set方法要和数据库中
 73      *             列名相对应。例如数据库列名为user_name,那么对象的方法就应该是setUserName/getUserName
 74      */
 75     public static <T> T RStoObject(CachedRowSet rs , Class<T> c)
 76             throws InstantiationException, IllegalAccessException,
 77             SQLException, NoSuchMethodException, RuntimeException,
 78             ClassNotFoundException, InvocationTargetException{
 79
 80          // 要确定该类有无参的构造方法
 81         T instance = c.newInstance() ;
 82         // 获取元数据,以便得到列的信息
 83         ResultSetMetaData metaData = rs.getMetaData() ;
 84         // 获取列数
 85         int columnNum = metaData.getColumnCount() ;
 86
 87         for(int i = 1 ; i <= columnNum ; i ++ ){
 88             String columnName = getColumnName(metaData.getColumnName(i)) ;
 89             Class columnClassType = SQLTypeToClass(metaData.getColumnType(i)) ;
 90             String columnTypeName = columnTypeToGetter(metaData.getColumnTypeName(i)) ;
 91             // 反射获取对象的set方法
 92             Method objectMethod = c.getMethod(
 93                             "set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1),
 94                             columnClassType
 95                             ) ;
 96             // 反射获取CachedRowSetImpl的get方法
 97             Method RSGetter = CachedRowSetImpl.class.getMethod(
 98                             "get"+columnTypeName.substring(0,1).toUpperCase()+columnTypeName.substring(1),
 99                              int.class) ;
100             // 执行RS的get方法获取属性值
101             Object value = RSGetter.invoke(rs,i) ;
102             // 执行Object的set方法为对象赋值
103             objectMethod.invoke(instance, value) ;
104         }
105         // 返回对象
106         return instance ;
107     }
108     /**
109      * 获取与数据库列名对应的属性名。
110      * 例如:
111      *         数据库列名                属性名
112      *         user_name/username        userName
113      * @param rawColumnName 数据库列名
114      * @return 与数据库列名对应的对象属性名
115      */
116     public static String getColumnName(String rawColumnName ){
117         if(rawColumnName.matches(".*_.*")){
118             String[] words = rawColumnName.split("_") ;
119             String firstWord = words[0].toLowerCase() ;
120             String lastWord = words[1].substring(0, 1).toUpperCase() + words[1].substring(1).toLowerCase() ;
121             String attributeName = firstWord + lastWord ;
122             return attributeName ;
123         }else{
124             /*
125              * 如果数据库列名不包含下划线,有可能只有一个单词,那么将首字母大写然后直接返回就行。
126              * 如果不止一个单词那就没辙了: 怎样让第二个单词首字母大写?
127              * 这里就暂时让其直接返回吧
128              * TODO : 怎样让第二个单词首字母大写
129              */
130             return rawColumnName.substring(0,1).toUpperCase() + rawColumnName.substring(1).toLowerCase() ;
131         }
132     }
133     public static String columnTypeToGetter(String columnType){
134         /**
135          * mysql数据库中存储字符串只有varchar,但是ResultSet接口中没有定义getVarchar()方法所以将varchar转换成String即可,
136          */
137         if(columnType.equals("VARCHAR")){
138             return "String" ;
139         }
140         if(columnType.equals("NVARCHAR2")){
141             return "String" ;
142         }
143         // oracle数据库NUMBER字段类型对应Java中int
144         if(columnType.equals("NUMBER")){
145             return "int" ;
146         }
147         return columnType ;
148     }
149     /**
150      * 将封装后的原始类型名称转换成原始类型的class
151      * @param columnType 封装后的对象名称例如"java.lang.Integer" , "java.lang.Float" , "java.lang.Double"
152      * @return 原始类型class类型 例如int.class float.class double.class
153      * @throws ClassNotFoundException
154      */
155     public static Class getColumnClassType(String columnType) throws ClassNotFoundException{
156         /**
157          * 数据库中的int、float、double等原始列类型当通过getColumnClassName()方法获取时,会将原始类型打包成其基础类型封装对象
158          * 例如 int --> Integer float --> Float double --> Double
159          * 该方法是为了将获取的基础类型封装类名转换成原始类型的class
160          */
161         if(columnType.equals("java.lang.Integer")){
162              return int.class ;
163         }
164         if(columnType.equals("java.lang.Float")){
165             return float.class ;
166         }
167         if(columnType.equals("java.lang.Double")){
168              return double.class ;
169         }
170         return Class.forName(columnType) ;
171     }
172     /**
173      * 将java.sql.Types类型转化成相应的Java中对应的Class
174      * @param SQLType java.sql.Types类型
175      * @return Class类型的实例例如 int.class
176      */
177     public static  Class SQLTypeToClass(int SQLType){
178         switch(SQLType){
179         case java.sql.Types.ARRAY : return String.class ;
180
181         case java.sql.Types.BIGINT : return int.class ;
182
183         case java.sql.Types.BIT : return byte.class ;
184
185         case java.sql.Types.BOOLEAN : return boolean.class ;
186
187         case java.sql.Types.CHAR : return char.class ;
188
189         case java.sql.Types.DOUBLE : return double.class ;
190
191         case java.sql.Types.FLOAT : return float.class ;
192
193         case java.sql.Types.INTEGER : return int.class ;
194
195         case java.sql.Types.LONGNVARCHAR : return String.class ;
196
197         case java.sql.Types.LONGVARCHAR : return String.class ;
198
199         case java.sql.Types.NCHAR : return String.class ;
200
201         case java.sql.Types.NVARCHAR :return String.class ;
202
203         case java.sql.Types.VARCHAR : return String.class ;
204         // 通过rs.getDate()获取到的java.sql.Date能够直接将其赋值到java.util.Date会进行自动转换
205         case java.sql.Types.DATE : return Date.class ;
206         // oracle数据库的Number字段类型对应NUMERIC类型
207         case java.sql.Types.NUMERIC : return int.class ;
208
209         default :return String.class ;
210         }
211     }
212     public static Date StringTodate(String dateString , String format ) throws ParseException{
213         SimpleDateFormat sdf = new SimpleDateFormat(format);
214           // 将时间字符串转换成java.util.Date对象
215         Date date = sdf.parse(dateString);
216         return date ;
217     }
218     public static java.sql.Date utildateTosqldate(Date date){
219         return new java.sql.Date(date.getTime());
220     }
221 }
时间: 2024-07-30 20:51:38

将CachedRowSet中的数据转储到对象中的相关文章

数据库中树结构数据,转换为Java对象树结构( 多叉树结构 )

总体就是图所表示所表示的转换,由数据库 => Java对象转换,代码比较简单,但对数据库压力可以大一点,多次查询. 主要是对象之间建立关联 No.2 : MapToTree() 思路为: 用pid(父id)作分组 ,这样每一个组的父节点是同一样,换句话说就是同一分组里,所有节点pid是相同的. 这样就针对分组操作,建立关联. 用Map做封装,key为父ID, value为分组List 用到了QueryRunner 这个是数据库工具,只要在网上找,下载就可以,能直接查询List. QueryRun

c#.net循环将DataGridView中的数据赋值到Excel中,并设置样式

Microsoft.Office.Interop.Excel.Application excel =                new Microsoft.Office.Interop.Excel.Application();            excel.SheetsInNewWorkbook = 1;            excel.Workbooks.Add(); //设置Excel列名            excel.Cells[1, 1] = "学号";     

如何使用免费控件将Word表格中的数据导入到Excel中

我通常使用MS Excel来存储和处理大量数据,但有时候经常会碰到一个问题—我需要的数据存储在word表格中,而不是在Excel中,这样处理起来非常麻烦,尤其是在数据比较庞大的时候, 这时我迫切地需要将word表格中的数据导入到Excel中.相信大家也碰到过同样的问题,下面我就给大家分享一下在C#中如何使用免费控件来实现这一功能.这里,我使用了两个免费API, DocX和Spire.Xls. 有需要的朋友可以下载使用.下载地址: DocX:codeplex官网 Spire.Xls: E-iceb

SQL SERVER 使用BULK Insert将txt文件中的数据批量插入表中(1)

1/首先建立数据表 CREATE TABLE BasicMsg( RecvTime FLOAT NOT NULL , --接收时间,不存在时间相同的数据 AA INT NOT NULL, --24位地址码 . FlightID Varchar(10) NULL, --航班号) 2/ 建立存储过程 USE DF17DataProIF EXISTS (SELECT * FROM SYS.PROCEDURES WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[BulkDataP

使用OpenXml把Excel中的数据导出到DataSet中

public class OpenXmlHelper { /// <summary> /// 读取Excel数据到DataSet中,默认读取所有Sheet中的数据 /// </summary> /// <param name="filePath">Excel文件路径</param> /// <param name="sheetNames">Sheet名称列表,默认为null查询所有Sheet中的数据<

Sql Server中的数据类型和Mysql中的数据类型的对应关系(转)

Sql Server中的数据类型和Mysql中的数据类型的对应关系(转):https://blog.csdn.net/lilong329329/article/details/78899477 一.SQL SERVER与MySQL数据存储的差异 1.SQL SERVER中的datetime,保留到微秒(秒后小数点3位),而mysql仅保留到秒,转换后是否会影响业务,如果影响,需要新增一个字段专门来存储微秒或者毫秒,虽然mysql中没有时间数据类型的精度到达微秒或者毫秒,但是mysql提供对微秒的

使用SqlBulkCopy将DataTable中的数据批量插入数据库中

#region 使用SqlBulkCopy将DataTable中的数据批量插入数据库中 /// <summary> /// 注意:DataTable中的列需要与数据库表中的列完全一致. /// </summary> /// <param name="conStr">数据库连接串</param> /// <param name="strTableName">数据库中对应的表名</param> //

根据SQL Server中的数据向矢量图层中添加点对象

SQL Server中的数据已有坐标信息(LAT,LNG) 在FormLoad事件中从SQL里获取数据并存储在DataSet. //在顶部定义SqlConnection对象 // public static string conStr = "server=(local);database=DbName;uid=sa;pwd=123"; //public SqlConnection conn = new SqlConnection(conStr); conn.Open();//打开数据库

需要向后台传递一个对象数据,但对象中包含数组,结果请求报错,500

一.背景,由于前后端交互经验匮乏,今天遇到了一个问题.发送一个对象给后端,对象中包含了一个数组,然后请求失败了... 1.提交前,打印出要提交的数据,如图: 2.然后,查看了控制台, 发现 "message"中的报错信息, 不能识别的属性 'agentAreas[0][areaId]',  但是我记得,对象中,我没有传这么奇怪的 键名啊. 3.于是,我继续查找,无意中,在 “Headers”中,最底部,查看到这样的数据, 如下图: ,出现这样的情况,那应该就是我 传入的数据有问题. 4