国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【JDBC系列】JDBC原生處理ResultSet

Warren / 2932人閱讀

摘要:背景最近在學習,在處理返回值與業務對象之間的轉換非常方便,定義,標明互相之間的轉換關系,即可輕松完成轉換。我們會寫使用原生的來獲取返回值。

背景

最近在學習Mybatis,Mybatis在處理JDBC返回值與Java業務對象之間的轉換非常方便,定義XML,標明互相之間的轉換關系,即可輕松完成轉換。
Mybatis是JDBC的封裝,我們先來看看如果用原生的JDBC,如何完成ResultSet和Java業務對象之間的轉換,會遇到哪些不便。

示例代碼 Java業務PO

CityPO,包含三個字段 id,cityId,cityName。我們會寫使用原生的JDBC來獲取返回值。

Integer id;

Long cityId;

String cityName;
獲取返回值
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo", "root", "123456");

PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM SU_City limit 10");
preparedStatement.execute();

ResultSet resultSet = preparedStatement.getResultSet();  //從數據庫獲取的數據
ResultSetMetaData meta = resultSet.getMetaData();        //從數據庫返回的數據的元數據,包含列的基本信息
int cols = meta.getColumnCount();        

List cityPOS = new ArrayList();
對象轉換

我們要完成的工作就是將ResultSet轉換為cityPOS。

方案一

一個比較笨的方法,就是依次判斷每個列的名字,因為開發者知道數據庫的哪一列對應的是業務PO中的哪個屬性,如果列名和屬性名相等,那么調用對應屬性的set方法,如下面的代碼所示。

while (resultSet.next()) {
    CityPO cityPO = new CityPO();
    for (int i = 1; i <= cols; i++) {
        if (meta.getColumnName(i).equals("id")) {
            cityPO.setId((Integer) resultSet.getObject(i));
        } else if (meta.getColumnName(i).equals("city_id")) {
            cityPO.setCity_id(Long.valueOf((Integer)resultSet.getObject(i)));
        } else if (meta.getColumnName(i).equals("city_name")) {
            cityPO.setCity_name((String) resultSet.getObject(i));
        }
        cityPOS.add(cityPO);
    }
}
缺點

轉換完全和具體的業務類綁定在了一起,你如果新處理一個業務類,你得再重新寫一套差不多的代碼,而且隨著類的屬性字段的增多,你的if/else代碼會越來越多,聽起來是不是很恐怖。

在調用set方法時,我們需要處理類型轉換,又是一長串的代碼。我們這個方案沒用反射,不知道set屬性的類型,只能靠人為判斷,很有可能出現異常。

我在cityPO.setCity_id(Long.valueOf((Integer)resultSet.getObject(i))) 就遇到了把Integer直接強轉Long失敗,報出了異常才改成了現在這樣,如果這樣的代碼出現在你應用的各個角落,你慌不?

結論

方案1的處理和具體的代碼綁定的比較死,依靠一堆判斷來完成賦值,那么我們想到可以利用反射來完成對屬性的賦值,這樣字段再多,也不怕啦。

方案二

利用反射,通過mysql字段的名稱,直接反射找到對應屬性的set方法,執行調用。簡單的代碼如下所示。

Class clazz = Class.forName("po.CityPO");
Object obj = clazz.newInstance();
for (int i = 1; i <= cols; i++) {
    Field field = null;
    field = clazz.getDeclaredField(meta.getColumnName(i));
    field.setAccessible(true);
    field.set(obj, resultSet.getObject(i));
}
cityPOS.add((CityPO) obj);

這段我為了測試,是直接把對應的對象的屬性名改成了數據庫中的列名。

缺點

因為是通過數據庫的列名反射出對應的方法,而通常我們在Java中使用的是駝峰命名,怎么處理列名到對象類名的轉換,這里應該有一定的代碼量,當然也可以在select的時候 as成對應的屬性名,這樣就解決了這個問題。

我們依然需要處理類型轉換。

我們可能會多選了一些列,而這個方案會統統去找反射的方法,可能會拋出異常。

結論

我覺得這應該是框架會采取的方案。

總結

直接用原生的JDBC完成數據庫到Java業務對象的轉換,肯定是非常繁瑣的,從目前來看,框架應該也是用的方案2,只不過會比方案案強大的多。

從使用Mybatis這一段時間來看,其在這個方案做了這么幾件事。

解決了數據庫列名到Java列名的映射。

解決了數據庫類型到Java類型的轉換工作。

在轉換過程中具備一定的容錯能力。

后續

后續會研究下Mybatis在這方面所做的工作和源碼,有興趣可以持續關注我的微信公眾號。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67417.html

相關文章

  • 談談Spring-Data的那些事兒

    摘要:什么是呢全稱,是提出的一個對象持久化規范,各應用服務器自主選擇具體實現。僅僅只是一個規范,而不是產品使用本身是不能做到持久化的。只要提供了持久化類與表的映射關系,框架在運行時就能參照映射文件的信息,把對象持久化到數據庫中。 我們在進行事務處理往往需要和數據庫進行交互,這其中有關系型數據庫(MySql,Sql Server,Oracle)或者是非關系型數據庫(Redis,Hadhoop)...

    chinafgj 評論0 收藏0
  • 談談Spring-Data的那些事兒

    摘要:什么是呢全稱,是提出的一個對象持久化規范,各應用服務器自主選擇具體實現。僅僅只是一個規范,而不是產品使用本身是不能做到持久化的。只要提供了持久化類與表的映射關系,框架在運行時就能參照映射文件的信息,把對象持久化到數據庫中。 我們在進行事務處理往往需要和數據庫進行交互,這其中有關系型數據庫(MySql,Sql Server,Oracle)或者是非關系型數據庫(Redis,Hadhoop)...

    charles_paul 評論0 收藏0
  • JDBC系列】從源碼角度理解JDBC和Mysql的預編譯特性

    摘要:我們對語句做適當改變,就完成了注入,因為普通的不會對做任何處理,該例中單引號后的生效,拉出了所有數據。查詢資料后,發現還要開啟一個參數,讓端緩存,緩存是級別的。結論是個好東西。 背景 最近因為工作調整的關系,都在和數據庫打交道,增加了許多和JDBC親密接觸的機會,其實我們用的是Mybatis啦。知其然,知其所以然,是我們工程師童鞋們應該追求的事情,能夠幫助你更好的理解這個技術,面對問題...

    longshengwang 評論0 收藏0

發表評論

0條評論

Warren

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<