标签:
虽然还有很多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 }
标签:
原文地址:http://www.cnblogs.com/caiyao/p/4771186.html