<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Sung in Blog

               一些技術文章 & 一些生活雜碎
    JDBC 抽象和數據存儲異常層次

    數據訪問是Spring 的另一個閃光點。

    JDBC 提供了還算不錯的數據庫抽象,但是需要用痛苦的API。這些問題包括:

      需要冗長的錯誤處理代碼來確保ResultSets,Statements以及(最重要的)Connections在使用后關閉。這意味著對JDBC的正確使用可以快速地導致大量的代碼量。它還是一個常見的錯誤來源。Connection leak可以在有負載的情況下快速宕掉應用程序。

      SQLException相對來說不能說明任何問題。JDBC不提供異常的層次,而是用拋出SQLException來響應所有的錯誤。找出到底哪里出錯了——例如,問題是死鎖還是無效的SQL?——要去檢查SQLState或錯誤代碼。這意味著這些值在數據庫之間是變化的。

    Spring用兩種方法解決這些問題:

      提供API,把冗長乏味和容易出錯的異常處理從程序代碼移到框架之中??蚣芴幚硭械漠惓L幚?;程序代碼能夠集中精力于編寫恰當的SQL和提取結果上。

      為你本要處理SQLException程序代碼提供有意義的異常層次。當Spring第一次從數據源取得一個連接時,它檢查元數據以確定數據庫。它使用這些信息把SQLException映射為自己從org.springframework.dao.DataAccessException派生下來的類層次中正確的異常。因而你的代碼可以與有意義的異常打交道,并且不需要為私有的SQLState或者錯誤碼擔心。Spring的數據訪問異常不是JDBC特有的,因而你的DAO并不一定會因為它們可能拋出的異常而綁死在JDBC上。

    Spring提供兩層JDBC API。第一個時,在org.springframework.jdbc.core包中,使用回調機制移動控制權——并且因而把錯誤處理和連接獲取和釋放——從程序的代碼移到了框架之中。這是一種不同的Inversion of Control,但是和用于配置管理的幾乎有同等重要的意義。

    Spring使用類似的回調機制關注其他包含特殊獲取和清理資源步驟的API,例如JDO(獲取和釋放是由PersistenceManager完成的),事務管理(使用JTA)和JNDI。Spring中完成這些回調的類被稱作template。

    例如,Spring的JdbcTemplate對象能夠用于執行SQL查詢并且在如下的列表中保存結果:

    代碼:
    JdbcTemplate template = new JdbcTemplate(dataSource);
    final List names = new LinkedList();
    template.query("SELECT USER.NAME FROM USER",
       new RowCallbackHandler() {
          public void processRow(ResultSet rs) throws SQLException {
             names.add(rs.getString(1));
          }
       });


    注意回調中的程序代碼是能夠自由拋出SQLException的:Spring將會捕捉到這些異常并且用自己的類層次重新拋出。程序的開發者可以選擇哪個異常,如果有的話,被捕捉然后處理。

    JdbcTemplate提供許多支持不同情景包括prepared statements和批量更新的方法。Spring的JDBC抽象有比起標準JDBC來說性能損失非常小,甚至在當應用中需要的結果集數量很大的時候。

    在org.springframework.jdbc.object包中是對JDBC的更高層次的抽象。這是建立在核心的JDBC回調功能基礎紙上的,但是提供了一個能夠對RDBMS操作——無論是查詢,更新或者是存儲過程——使用Java對象來建模的API。這個API部分是受到JDO查詢API的影響,我發現它直觀而且非常有用。

    一個用于返回User對象的查詢對象可能是這樣的:

    代碼:

    class UserQuery extends MappingSqlQuery {

       public UserQuery(DataSource datasource) {
          super(datasource, "SELECT * FROM PUB_USER_ADDRESS WHERE USER_ID = ?");
          declareParameter(new SqlParameter(Types.NUMERIC));
          compile();
       }

       // Map a result set row to a Java object
       protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
          User user = new User();
          user.setId(rs.getLong("USER_ID"));
          user.setForename(rs.getString("FORENAME"));
          return user;
       }

       public User findUser(long id) {
          // Use superclass convenience method to provide strong typing
          return (User) findObject(id);
       }
    }

    這個類可以在下面用上:
    代碼:

    User user = userQuery.findUser(25);

    這樣的對象經常可以用作DAO的inner class。它們是線程安全的,除非子類作了一些超出常規的事情。

    在org.springframework.jdbc.object包中另一個重要的類是StoredProcedure類。Spring讓存儲過程通過帶有一個業務方法的Java類進行代理。如果你喜歡的話,你可以定義一個存儲過程實現的接口,意味著你能夠把你的程序代碼從對存儲過程的依賴中完全解脫出來。

    Spring數據訪問異常層次是基于unchecked(運行時)exception的。在幾個工程中使用了Spring之后,我越來越確信這個決定是正確的。

    數據訪問異常一般是不可恢復的。例如,如果我們不能鏈接到數據庫,某個業務對象很有可能就不能完成要解決的問題了。一個可能的異常是optimistic locking violation,但是不是所有的程序使用optimistic locking。強制編寫捕捉其無法有效處理的致命的異常通常是不好的。讓它們傳播到上層的handler,比如servlet或者EJB 容器通常更加合適。所有的Spring對象訪問異常都是DataAccessException的子類,因而如果我們確實選擇了捕捉所有的Spring數據訪問異常,我們可以很容易做到這點。

    注意如果我們確實需要從unchecked數據訪問異常中恢復,我們仍然可以這么做。我們可以編寫代碼僅僅處理可恢復的情況。例如,如果我們認為只有optimistic locking violation是可恢復的,我們可以在Spring的DAO中如下這么寫:

    代碼:

    try {
       // do work
    }
    catch (OptimisticLockingFailureException ex) {
       // I'm interested in this
    }

    如果Spring的數據訪問異常是checked的,我們需要編寫如下的代碼。注意我們還是可以選擇這么寫:
    代碼:

    try {
       // do work
    }
    catch (OptimisticLockingFailureException ex) {
       // I'm interested in this
    }
    catch (DataAccessException ex) {
       // Fatal; just rethrow it
    }

    第一個例子的潛在缺陷是——編譯器不能強制處理可能的可恢復的異?!@對于第二個也是如此。因為我們被強制捕捉base exception(DataAccessException),編譯器不會強制對子類(OptimisticLockingFailureException)的檢查。因而編譯器可能強制我們編寫處理不可恢復問題的代碼,但是對于強制我們處理可恢復的問題并未有任何幫助。

    Spring對于數據訪問異常的unchecked使用和許多——可能是大多數——成功的持久化框架是一致的。(確實,它部分是受到JDO的影響。)JDBC是少數幾個使用checked exception的數據訪問API之一。例如TopLink和JDO大量使用unchecked exception。Gavin King現在相信Hibernate也應該選擇使用unchecked exception。

    Spring的JDBC能夠用以下辦法幫助你:


      你決不需要在使用JDBC時再編寫finally block。

      總的來說你需要編寫的代碼更少了

      你再也不需要挖掘你的RDBMS的文檔以找出它為錯誤的列名稱返回的某個罕見的錯誤代碼。你的程序不再依賴于RDBMS特有的錯誤處理代碼。

      無論使用的是什么持久化技術,你都會發現容易實現DAO模式,讓業務代碼無需依賴于任何特定的數據訪問API。

    在實踐中,我們發現所有這些都確實有助于生產力的提高和更少的bug。我過去常常厭惡編寫JDBC代碼;現在我發現我能夠集中精力于我要執行的SQL,而不是煩雜的JDBC資源管理。

    如果需要的話Spring的JDBC抽象可以獨立使用——不強迫你把它們用作Spring的一部分。
    posted on 2005-10-26 15:53 Sung 閱讀(333) 評論(0)  編輯  收藏 所屬分類: Java
    主站蜘蛛池模板: 69免费视频大片| 免费亚洲视频在线观看| 亚洲精品人成网线在线播放va | 青青操视频在线免费观看| 在线观看亚洲一区二区| 在线jyzzjyzz免费视频| 高清永久免费观看| 亚洲乱码一二三四区国产| 婷婷亚洲天堂影院| 69xx免费观看视频| 国产精品美女免费视频观看| 亚洲精品**中文毛片| 四虎免费影院4hu永久免费| 国产免费一区二区三区在线观看| 亚洲欧洲无码AV不卡在线| 国产成人亚洲精品青草天美| 国产青草视频免费观看97| 国产精品免费一区二区三区四区| 亚洲精品国产精品| 久久亚洲精品人成综合网 | 久久久久久久久亚洲| 四虎在线免费播放| 鲁大师在线影院免费观看| 日韩毛片在线免费观看| 亚洲人成在线精品| 国产亚洲高清不卡在线观看| 日韩免费三级电影| 久久久久av无码免费网| 一个人看的免费观看日本视频www 一个人看的免费视频www在线高清动漫 | 在线人成免费视频69国产| 亚洲性无码AV中文字幕| 色婷婷六月亚洲婷婷丁香| 国产乱辈通伦影片在线播放亚洲 | 亚洲国产美国国产综合一区二区| 国产免费无遮挡精品视频| 四虎成年永久免费网站 | 暖暖在线日本免费中文| 日韩不卡免费视频| a毛片免费全部播放完整成| 男女超爽视频免费播放| 中文字幕亚洲精品无码|