麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

將CachedRowSet中的數據轉儲到對象中

2019-11-15 01:19:03
字體:
來源:轉載
供稿:網友
將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  * @version 2.0  23  *  24  * @modifyTime : 2015-9-1 25  */ 26 public class Convert { 27     /** 28      * 將CachedRowSetImpl中的多條記錄存儲進List中 29      * @param cachedRS CachedRowSetImpl結果集 30      * @param c List中元素類型 31      * @return ArrayList對象 32      * @throws SQLException  cachedRS.next()導致的異常 33      * @throws RuntimeException  34      * @throws InvocationTargetException  35      * @throws ClassNotFoundException  36      * @throws NoSuchMethodException  37      * @throws IllegalaccessException  38      * @throws InstantiationException  39      */ 40     public static <T> ArrayList<T> RStoList(CachedRowSet cachedRS , Class<T> c) 41             throws SQLException, InstantiationException, IllegalAccessException,  42             NoSuchMethodException, ClassNotFoundException, InvocationTargetException,  43             RuntimeException{ 44         if(!cachedRS.next()){ 45             return null ; 46         } 47         cachedRS.PRevious() ;// 由于上面執行了next,所有這里需要將指針移動到上一行 48         ArrayList<T> store = new ArrayList<T>() ; 49         while(cachedRS.next()){ 50             T object = RStoObject(cachedRS , c ) ; 51             store.add(object) ; 52         } 53         return store ; 54     } 55      56     /** 57      * 將ResultSet類型的結果集轉換成Object類型的對象 58      *  注:  59      * 1. 該方法只能轉換只有一條結果的CachedRowSet。  60      * 2.rs結果集中得到的值xxx,在類中要有相應的setXxx方法 61      *  62      * @param rs 63      *            結果集 64      * @param c 65      *            Class類型的值,可以通過Class.forName(類名)獲取,要確定該類有無參的構造方法, 66      *            否則會出現InstantiationException異常 67      * @return 轉換之后的對象 68      * @throws InstantiationException 69      * @throws IllegalAccessException 70      * @throws SQLException 71      * @throws RuntimeException 72      * @throws NoSuchMethodException 73      * @throws ClassNotFoundException 74      * @throws InvocationTargetException 75      *             注:  76      *                1. 該方法只能轉換只有一條結果的CachedRowSet。  77      *                2.rs結果集中得到的值xxx,在類中要有相應的setXxx方法 78      *             3. 在單獨調用這個方法的時候(不是通過RStoList的間接調用)。 79      *             需要在傳遞CachedRowSet這個參數之前調用rs的next()方法。否則會出現指針無效的錯誤 80      *             4. 使用該方法將結果集中的數據轉儲到對象中時,要對象中屬性get/set方法要和數據庫中 81      *             列名相對應。例如數據庫列名為user_name,那么對象的方法就應該是setUserName/getUserName 82      */ 83     public static <T> T RStoObject(CachedRowSet rs , Class<T> c) 84             throws InstantiationException, IllegalAccessException,  85             SQLException, NoSuchMethodException, RuntimeException,  86             ClassNotFoundException, InvocationTargetException{ 87          // 要確定該類有無參的構造方法 88         T instance = c.newInstance() ; 89         // 獲取元數據,以便得到列的信息 90         ResultSetMetaData metaData = rs.getMetaData() ; 91         // 獲取列數 92         int columnNum = metaData.getColumnCount() ; 93          94         for(int i = 1 ; i <= columnNum ; i ++ ){ 95             String columnName = getColumnName(metaData.getColumnName(i)) ; 96             Class<?> columnClassType = SQLTypeToClass(metaData.getColumnType(i)) ; 97             columnClassType = getColumnClassType(columnName , columnClassType , c ) ; 98             String columnTypeName = columnTypeToGetter(metaData.getColumnTypeName(i)) ; 99             // 反射獲取對象的set方法100             Method objectMethod = c.getMethod(101                             "set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1), 102                             columnClassType103                             ) ;104             // 反射獲取CachedRowSetImpl的get方法105             Method RSGetter = CachedRowSetImpl.class.getMethod(106                             "get"+columnTypeName.substring(0,1).toUpperCase()+columnTypeName.substring(1), 107                              int.class) ;108             // 執行RS的get方法獲取屬性值109             Object value = RSGetter.invoke(rs,i) ;110             // 執行Object的set方法為對象賦值111             objectMethod.invoke(instance, value) ;112         }113         // 返回對象114         return instance ;115     }116     117     /**118      * 判斷類c是否存在set'columnName'('columnClassType' x)方法。119      * 如果不存在,再尋找是否存在set'columnName'('cloumnClassType的父類' x)方法,如果存在返回cloumnClassType的父類。120      * 如果存在,則返回cloumnClassType原值。121      * @param columnName 類c的屬性名122      * @param columnClassType 類c set方法的參數類型123      * @param c 類c124      * @return set方法的屬性類型125      */126     private static Class<?> getColumnClassType(String columnName , Class<?> columnClassType , Class<?> c ){127         /*128          * 寫該方法的原因:129          * int/double 在Oracle數據庫中都是用Number表示。130          * 所以從數據庫中查詢出來的數據無法辨別是int還是double, 也就導致無法正確通過反射獲取對象的set方法,因為方法參數無法確定。131          * 例如: Student表中有兩個屬性 int a , double b ;132          * 存入數據庫中就是都是Number,從數據庫中取出也都是Number。133          * 如果將Number對應于java的int,那么SQLTypeToClass()方法返回的就是int.class,134          * 無論從數據庫中查詢出來的是int還是double,因此,下面獲取set方法就只能獲取以int為參數的方法。 所以就無法獲取到double135          * b 的set方法。 反射獲取方法是確定的,不會在找不到int參數方法時轉而去找double參數方法。136          * 該方法為了在找不到int為參數的方法時,繼而找以double類型參數的方法。137          * 或者以后會添加找不到子類類型為參數的方法繼而找以其父類為參數的方法。138          */139             try {140                 c.getMethod("set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1), columnClassType).getName() ;141             } catch (NoSuchMethodException e) {142                 return getSuperColumnClassType(columnClassType) ;143             } catch (SecurityException e) {}144             return columnClassType ;145     }146     /**147      * 獲取columnClassType的父類148      * @param columnClassType 149      * @return150      */151     private static Class<?> getSuperColumnClassType(Class<?> columnClassType){152         if(columnClassType.equals(int.class)){153             return double.class ;154         }else{155             return columnClassType.getSuperclass() ;156         }157         158     }159     /**160      * 獲取與數據庫列名對應的屬性名。161      * 例如:162      *         數據庫列名                屬性名163      *         user_name/username        userName164      * @param rawColumnName 數據庫列名165      * @return 與數據庫列名對應的對象屬性名166      */167     public static String getColumnName(String rawColumnName ){168         if(rawColumnName.matches(".*_.*")){169             String[] Words = rawColumnName.split("_") ;170             String firstWord = words[0].toLowerCase() ;171             String lastWord = words[1].substring(0, 1).toUpperCase() + words[1].substring(1).toLowerCase() ;172             String attributeName = firstWord + lastWord ;173             return attributeName ;174         }else{175             /*176              * 如果數據庫列名不包含下劃線,有可能只有一個單詞,那么將首字母大寫然后直接返回就行。177              * 如果不止一個單詞那就沒轍了: 怎樣讓第二個單詞首字母大寫?178              * 這里就暫時讓其直接返回吧 179              * TODO : 怎樣讓第二個單詞首字母大寫180              */181             return rawColumnName.substring(0,1).toUpperCase() + rawColumnName.substring(1).toLowerCase() ;182         }183     }184     public static String columnTypeToGetter(String columnType){185         /**186          * MySQL數據庫中存儲字符串只有varchar,但是ResultSet接口中沒有定義getVarchar()方法所以將varchar轉換成String即可,187          */188         if(columnType.equals("VARCHAR")){189             return "String" ;190         }191         if(columnType.equals("NVARCHAR2")){192             return "String" ;193         }194         // oracle數據庫NUMBER字段類型對應Java中int195         if(columnType.equals("NUMBER")){196             return "int" ;197         }198         if(columnType.toLowerCase().equals("timestamp")){199             return "object" ;200         }201         return columnType.toLowerCase() ;202     }203     /**204      * 將封裝后的原始類型名稱轉換成原始類型的class205      * @param columnType 封裝后的對象名稱例如"java.lang.Integer" , "java.lang.Float" , "java.lang.Double"206      * @return 原始類型class類型 例如int.class float.class double.class207      * @throws ClassNotFoundException 208      */209     public static Class<?> getColumnClassType(String columnType) throws ClassNotFoundException{210         /**211          * 數據庫中的int、float、double等原始列類型當通過getColumnClassName()方法獲取時,會將原始類型打包成其基礎類型封裝對象 212          * 例如 int --> Integer float --> Float double --> Double213          * 該方法是為了將獲取的基礎類型封裝類名轉換成原始類型的class214          */215         if(columnType.equals("java.lang.Integer")){216              return int.class ;217         }218         if(columnType.equals("java.lang.Float")){219             return float.class ;220         }221         if(columnType.equals("java.lang.Double")){222              return double.class ;223         }224         return Class.forName(columnType) ;225     }226     /**227      * 將java.sql.Types類型轉化成相應的Java中對應的Class228      * @param SQLType java.sql.Types類型229      * @return Class類型的實例例如 int.class230      */231     public static  Class<?> SQLTypeToClass(int SQLType){232         switch(SQLType){233         case java.sql.Types.ARRAY : return String.class ;234         235         case java.sql.Types.BIGINT : return int.class ;236         237         case java.sql.Types.BIT : return byte.class ;238         239         case java.sql.Types.BOOLEAN : return boolean.class ;240         241         case java.sql.Types.CHAR : return char.class ;242         243         case java.sql.Types.DOUBLE : return double.class ;244         245         case java.sql.Types.FLOAT : return float.class ;246         247         case java.sql.Types.INTEGER : return int.class ;248         249         case java.sql.Types.LONGNVARCHAR : return String.class ;250         251         case java.sql.Types.LONGVARCHAR : return String.class ;252         253         case java.sql.Types.NCHAR : return String.class ;254         255         case java.sql.Types.NVARCHAR :return String.class ;256         257         case java.sql.Types.VARCHAR : return String.class ;258         // 通過rs.getDate()獲取到的java.sql.Date能夠直接將其賦值到java.util.Date會進行自動轉換259         case java.sql.Types.DATE : return Date.class ;260         // oracle數據庫的Number字段類型對應NUMERIC類型,261         //但是在數據庫中整數和浮點數都是Number,262         //所以在應用中無法判斷從數據庫中取出的是整數還是浮點數.263         //處理方法是:在應用中都使用浮點數264         case java.sql.Types.NUMERIC : return int.class ;265         // 由于sun包中提供的CachedRowSetImpl類存在bug,當getTimestamp()字段時會出現類轉換異常。266         // 解決方案有:267         // 1. 換類。oracle驅動包oracle.jdbc.rowset.OracleCachedRowSet類(大概是這個名字)可以正確執行。268         // 2. 換oracle驅動版本。10.0以上,這個我沒有試過,有些人說可以。269         // 3. 如果使用sun提供的這個類,獲取Timestamp時使用getObject()。然后再轉換。270         // 因為考慮到該類的通用性,所以采用第三種解決方案。271         case java.sql.Types.TIMESTAMP : return Object.class ;272         273         default :return String.class ;274         }275     }276     public static Date StringTodate(String dateString , String format ) throws ParseException{277         SimpleDateFormat sdf = new SimpleDateFormat(format);  278           // 將時間字符串轉換成java.util.Date對象  279         Date date = sdf.parse(dateString);  280         return date ;281     }282     public static java.sql.Date utildateTosqldate(Date date){283         return new java.sql.Date(date.getTime());284     }285 }


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 毛片观看网址 | 日本精品免费观看 | 老司机免费福利午夜入口ae58 | 国产亚洲欧美日韩高清 | 伊人亚洲精品 | 91网站链接 | 亚洲人成电影在线 | 天堂成人国产精品一区 | 失禁高潮抽搐喷水h | 性欧美日本 | 国产激情网 | 一区二区久久久久草草 | 国产精品剧情一区二区在线观看 | 日日鲁一鲁视频 | 欧美男女爱爱视频 | 欧美性生活久久久 | 国产91丝袜在线播放0 | 成人爱爱电影 | 国产手机国产手机在线 | 久久中出 | 黑人一区二区三区四区五区 | 久久精品1区2区 | 久草在线看片 | 午夜小影院 | 欧美成人做爰高潮片免费视频 | 国产一区二区免费在线观看视频 | 双性精h调教灌尿打屁股的文案 | 一本色道久久99精品综合蜜臀 | av黄色片网站 | 亚洲成人在线免费 | 草草久久久 | 曰韩精品| 亚洲综人网 | 今井夏帆av一区二区 | 99爱在线免费观看 | 国产自91精品一区二区 | 暴力强行进如hdxxx | 性爱视频在线免费 | 91免费视频版 | 欧美偷拍一区二区 | 久久久久久久久久久久网站 |