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

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

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

    狂奔 lion

    自強(qiáng)不息

    [譯]JDBC4.0具有哪些新特性?

    Java SE 6 所提供的諸多新特性和改進(jìn)中,值得一提的是為 Java 程序提供數(shù)據(jù)庫訪問機(jī)制的 JDBC 版本升級到了 4.0, 這個(gè)以 JSR-221 為代號的版本 , 提供了更加便利的代碼編寫機(jī)制及柔性 , 并且支持更多的數(shù)據(jù)類型 . 在本文中,我們將從編碼的易用性及柔性的角度探討 JDBC 4.0 所帶來的新特性及改進(jìn)。
    JDBC 4.0 的新特性

    JDBC 4.0 文檔列舉了 20 個(gè)改進(jìn)及新特性 , 大小不等 . 本文無法做到盡述其詳 , 為此筆者根據(jù)其功能特點(diǎn)及應(yīng)用領(lǐng)域?qū)⑵浞譃橄率鏊念悾?/span>

    1.     驅(qū)動(dòng)及連接管理

    2.     異常處理

    3.     數(shù)據(jù)類型支持

    4.     API 的變化

    下面按照上述四類展開詳述:

    驅(qū)動(dòng)及連接管理

    驅(qū)動(dòng)及連接的使用和結(jié)果集管理 JDBC 的很多地方都發(fā)生了顯著的變化

    連接數(shù)據(jù)庫變得更加容易

    如果您曾經(jīng)有過 JDBC 開發(fā)的經(jīng)驗(yàn) , 那么我確信您還保存著一份建立數(shù)據(jù)庫連接所必須的工作列表 . 而列表中的第一項(xiàng)即加載一個(gè)合適的驅(qū)動(dòng)程序 . 您是否想過這個(gè)步驟應(yīng)該被改進(jìn)呢 ? 在此版 JDBC 中做到了 . 您不必再顯式地加載 Class.forName . 當(dāng)您的程序首次試圖連接數(shù)據(jù)庫時(shí) , DriverManager 自動(dòng)加載驅(qū)動(dòng)到當(dāng)前應(yīng)用的 CLASSPATH . 這是 JDBC 的一個(gè)比較大的改動(dòng) .

    盡管 DriverManager 現(xiàn)在可以自動(dòng)地加載驅(qū)動(dòng) , 建立一個(gè) DataSource 對象 仍是獲取連接的推薦的方法 . 因?yàn)榭梢栽谂渲弥袑?shù)據(jù)源指向不同的數(shù)據(jù)庫, DataSource 更具透明性和靈活性。 這樣就可以訪問另一個(gè)數(shù)據(jù)庫實(shí)例不需更改現(xiàn)有的任意一行代碼 , 甚至數(shù)據(jù)庫的驅(qū)動(dòng)完全不同也沒有關(guān)系 .

    ResultSet 的使用變得更為靈活

    ResultSet 接口的層次結(jié)構(gòu)當(dāng)前為編程的靈活性提供了一些新的機(jī)制 . RowSet 子接口滾動(dòng)、可提交并可離線編輯的 ResultSet . WebRowSet 子接口提供了從數(shù)據(jù)庫表中獲取數(shù)據(jù) , 并將其序列化為 XML 文檔 , 抑或是將 XML 解析成 result set 的能力 . 盡管上個(gè)版本的 JDBC 也提供了 RowSet 接口層次 ,當(dāng)前的版本對于 SQLXML 數(shù)據(jù)類型支持得更好 ( 稍后討論 ) ,這些特性是的 JDBC 編程更加容易且具靈活性 .

    提供了更多的 API

    本版 JDBC 提供了更多的 API 以實(shí)現(xiàn)訪問 SQL:2003 具備的新特性 . 此外 , 為了更好的操縱修改數(shù)據(jù), JDBC 也增添了許多的方法。 .

    現(xiàn)在我們來看一些代碼并討論下面 Example1 類的輸出結(jié)果 . 它將連接嵌入式的 Apache Derby 數(shù)據(jù)庫并在控制臺上顯示輸出結(jié)果 . 盡管 JDBC 4.0 已推出幾個(gè)月了 , 筆者發(fā)現(xiàn)只有 Apache Derby 提供了支持 JDBC 4.0 規(guī)范的驅(qū)動(dòng) ( 截至 2007 3 ). 本文的所有例子均用 JDK 1.6 Apache Derby 數(shù)據(jù)庫 10.2.2.0 開發(fā) .

     

    public class Example1 {

      public static void main(String[] args) {

        ...

        String dbName = "example1";

        String tableName = "stu1";

        ds = new EmbeddedDataSource40();

        ds.setDatabaseName(dbName);

        String connectionURL = "jdbc:derby:"+dbName+";create=true";

        try {

          con = ds.getConnection();

          stmt = con.createStatement();

          rs = stmt.executeQuery("select * from "+tableName);

          int colCount= rs.getMetaData().getColumnCount();

          for (int j=0; j< colCount; j++){

            System.out.print(rs.getMetaData().getColumnName(j+1)

              + "\t");

          }

          while (rs.next()) {

            System.out.print("\n");

            for (int i = 0; i < colCount; i++) {

             System.out.print(rs.getString(i + 1) + "\t");

            }

          }

         } catch (SQLException e) {

               e.printStackTrace();

             }

         finally{

          //close connections

         }

       }

    }

     

    如果在 example1 數(shù)據(jù)庫的 stu1 表中有數(shù)據(jù)的話 , 編譯并運(yùn)行 Example1.java 將在控制臺獲得以下輸出:

     

    ID    NAME            COURSE

    1001  John Doe        Statistics    

    1002  Jack McDonalds  Linear Algebra

     

    如果想看 DriverManager 如何自動(dòng)加載 JDBC 驅(qū)動(dòng) , 可以將 Example1 中的: con=ds.getConnection() 替換為: con=DriverManager.getConnection(connectionURL) . 該類將產(chǎn)生相同的輸出。正如您所看到的,再也不用顯式地調(diào)用 Class.forName() .

    異常處理

    怎樣辨別一個(gè) Java 程序的健壯與否呢 ? 在我看來,異常處理機(jī)制是重要的考慮因素之一 . 一個(gè)健壯的 Java 程序可以很好地處理異常 , 并給予程序在發(fā)生異常時(shí)恢復(fù)的能力 . 而一個(gè)不健壯的程序?qū)?dǎo)致輸出錯(cuò)誤的結(jié)果甚至導(dǎo)致整個(gè)應(yīng)用的崩潰 !

    JDBC 4.0 增加了一些簡單而有力的異常處理機(jī)制 , 其中值得一提的是鏈?zhǔn)疆惓#绻@個(gè)異常鏈存在的話,即可應(yīng)用增強(qiáng)了的 for - each 循環(huán)來獲取異常鏈 ,. 下面的 Example2 類的局部結(jié)構(gòu)展示了如何應(yīng)用這種新的方法處理鏈?zhǔn)疆惓#?/span>

     

    public class Example2 {

      public static void main(String[] args) {

        String dbName = "example";

        String tableName = "student4";

        try {

          con = ds.getConnection();

              stmt = con.createStatement();

          rs = stmt.executeQuery("select * from " + tableName);

        } catch (SQLException sx) {

          for(Throwable e : sx ) {

            System.err.println("Error encountered: " + e);

          }

        }

        finally{

          //close connections

        }

      }

    }

     

    運(yùn)行 Example2.java , 注意 student4 并不是數(shù)據(jù)庫中實(shí)際存在的表 . 將在下列調(diào)用中產(chǎn)生鏈?zhǔn)疆惓#?/span>

     

    rs = stmt.executeQuery("select * from " + tableName);

     

    在實(shí)際的應(yīng)用中,需要捕捉到這些異常 , 檢測并進(jìn)行相應(yīng)的處理 . 在本例中,筆者僅將其在控制臺輸出 . 以下是輸出代碼:

     

    for(Throwable e : sx ) {

      System.err.println("Error encountered: " + e);

    }

     

    以下是類 Example2 輸出的結(jié)果 :

     

    Error encountered: java.sql.SQLSyntaxErrorException:

       Table/View 'STUDENT4' does not exist.

    Error encountered: java.sql.SQLException:

       Table/View 'STUDENT4' does not exist.

    Exception in thread "main" java.lang.NullPointerException

       at ex.Examlpe2.main(Examlpe2.java:51)

     

    通過應(yīng)用 JDBC 4.0, 您現(xiàn)在不需太多代碼即可以獲取及遍歷異常鏈 . 在以往的版本中 , 您在遍歷異常鏈時(shí),必須手工的調(diào)用 getNextException 方法才能得到相同的效果 .

    支持的數(shù)據(jù)類型

    本版 JDBC 增加了一些新的數(shù)據(jù)類型,對其他的一些數(shù)據(jù)類型,則提供了更好的支持 . 筆者為 XML 被正式支持感到欣喜 , 本版中產(chǎn)生了一個(gè)新的接口 : SQLXML . 在筆者看來這個(gè)接口值得單獨(dú)開一個(gè)章節(jié)為其討論:

    SQLXML XML 的支持

    SQLXML SQL XML 數(shù)據(jù)類型在 Java 中的表示, XML SQL 中用于表示表中 XML 數(shù)據(jù)的內(nèi)建數(shù)據(jù)類型 . 在默認(rèn)的情況下, JDBC 驅(qū)動(dòng)將 SQLXML 指針指向 XML 數(shù)據(jù)而不是數(shù)據(jù)本身 . SQLXML 對象在其被創(chuàng)建的事務(wù)中是穩(wěn)定的 .

    在下面的 Example3 類中 , 筆者將說明如何在當(dāng)前連接中應(yīng)用 SQLXML 并更新表數(shù)據(jù) .

      public class Example3 {

        public static void main(String[] args) {

          ...

          con = ds.getConnection();

          SQLXML sx= con.createSQLXML();

          sx.setString("Math is Fun");

          String psx ="insert into "+tableName+

            " ( id, textbook) values(?,?) ";

          PreparedStatement pstmt = con.prepareStatement(psx);

          pstmt.setString(1,"1000");

          pstmt.setSQLXML(2,sx);

          pstmt.executeUpdate();

              ...

          }

        }

    這個(gè)例子說明了您所能應(yīng)用的最簡單的情況 . 如果我們繼續(xù)深入研究,事情就會(huì)變得有趣得多了 . 但在我們深入討論之前 , 讓我來告訴您運(yùn)行 Example3.java . 的結(jié)果。 非常不幸 , 我無法獲取到 SQLXML 對象,并得到了以下讓人失望的輸出:

    java.sql.SQLFeatureNotSupportedException: Feature not

       implemented: no details.

    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.

       getSQLException(Unknown Source)

    ... ... ... ...

    at ex.Example3.main(Example3.java:62)

    看來 Apache Derby 并沒有提供從 Connection 中獲取 SQLXML 對象的方法 . 但至少您可以看到筆者正試圖在類 Example3 中實(shí)現(xiàn)的東西 : 我想插入一行新的數(shù)據(jù): id 列值為 1000 textbook (S QLXML 類型 ) 插入 Math is Fun .

    筆者用如下代碼段結(jié)束關(guān)于 SQLXML 的討論,這段代碼從數(shù)據(jù)庫中讀取 XML 值并將其轉(zhuǎn)化為 Document 對象 .

    SQLXML sqlxml = rs.getSQLXML(column);

    InputStream binaryStream = sqlxml.getBinaryStream();

    DocumentBuilder parser =

      DocumentBuilderFactory.newInstance().newDocumentBuilder();

    Document doc = parser.parse(binaryStream);

    可以把一個(gè)列的值直接轉(zhuǎn)化為 XML 文檔不是一件令人興奮的事情嗎 ? 我覺得這個(gè)特性非常好 .

    ROWID 數(shù)據(jù)類型

    SQL ROWID 唯一標(biāo)識了數(shù)據(jù)表中的一行,并是訪問該行的最快的方法, 本版增加了 RowId 接口以提供對 ROWID SQL 數(shù)據(jù)類型在 Java 類中的支持 .

    對大對象類型支持的增強(qiáng)

    JDBC 版本 2 提供了對大的 SQL 對象如: CLOB , BLOB , ARRAY 的支持 , 及用于添加相關(guān)接口的 Struct: Clob , Blob , Array , and Struct . 在本版的 JDBC 中增加了很多對這些對象訪問的新方法 . 筆者將在 API 變化一節(jié)中進(jìn)行詳細(xì)論述 .

    支持 National Character Set NCS 轉(zhuǎn)化

    SQL:2003 提出了如下 SQL 數(shù)據(jù)類型的支持: NCHAR , NVARCHAR , LONGNVARCHAR , NCLOB . 其功用和 CHAR , VARCHAR , LONGVARCHAR , CLOB 類似 ,其區(qū)別僅是,這些類型的文本是用 NCS 編碼的。 如果需要大量的字符處理,您可能更傾向于 NCS 數(shù)據(jù)類型而非普通的數(shù)據(jù)類型。本版 JDBC 提供了增強(qiáng)對 NCS 支持的 API.

    • PreparedStatement , CallableStatement , ResultSet 接口中增加了一些 setter updater 方法以支持 NCS 轉(zhuǎn)化 . 比如方法 setNString , setNCharacterStream , setNClob 等等 .
    • SQLInput and SQLOutput 接口中增加了讀寫方法以支持 t NClob NString 對象 .

    API 變化

    JDBC 4.0 最大的變化來自于 API, 筆者在本小節(jié)對其做簡單介紹 .

    Array

    Array 接口增加了一個(gè) free 方法來釋放 array 對象及其持有的資源 .

    Connection PooledConnection

    Connection 接口現(xiàn)在提供一系列創(chuàng)建大對象的方法如 createClob , createBlob 等等 . 此外還有 getter setter 對客戶端信息的重載方法 , 及驗(yàn)證當(dāng)前連接正確性的方法 .

    PooledConnection 接口當(dāng)前提供 addStatementEventListener removeStatementEventListener 兩個(gè)方法來注冊和注銷 StatementEventListener 接口 , 這個(gè)接口是在本版 JDBC 中新引入的 . 這個(gè)接口的一個(gè)實(shí)例將獲取到 S tatement 池中 PreparedStatement s 的變化 . 比如,在注冊以后 , 當(dāng)驅(qū)動(dòng)調(diào)用 statementClosed 方法時(shí),所有 StatementEventListener 將獲得 statement 已關(guān)閉的通知 .

    DatabaseMetaData

    不同的關(guān)系數(shù)據(jù)庫往往支持不同的特性 , 并通過不同的方法來實(shí)現(xiàn)這些特性 , 并可能會(huì)是用不同的數(shù)據(jù)類型 . 這將會(huì)導(dǎo)致移植性的問題,因?yàn)楦鶕?jù)實(shí)現(xiàn)的不同,無法保證代碼在所有關(guān)系數(shù)據(jù)庫上都能正確執(zhí)行 . 這樣的問題在一定程度上可以通過這個(gè)接口所獲得的信息來解決 . 比如,如果您在寫一個(gè)通過傳入 SQL 語句來建立表的代碼 . 您可能想知道在 CREATE TABLE 語句中有哪些數(shù)據(jù)類型是可用的,此時(shí)可以調(diào)用該接口中的 getTypeInfo 方法 .

    本版 JDBC 增加了一些獲取信息的方法 . Example4 , 我將通過一段代碼展示如何獲得滿足某種模式的數(shù)據(jù)庫結(jié)構(gòu)的列表。 .

     

    con = ds.getConnection();

    DatabaseMetaData dmd = con.getMetaData();

    rs=dmd.getSchemas("TABLE_CAT", "SYS%");

    //iterate over the rs and print to console

     

    首先通過調(diào)用 dmd.getCatalogs 并遍歷結(jié)果集 , 得到了唯一的一個(gè)值: TABLE_CAT . 接著通過調(diào)用 rs=dmd.getSchemas("TABLE_CAT", "SYS%") 得到以 SYS 開頭的數(shù)據(jù)庫和表結(jié)構(gòu) . 以下是筆者得到的結(jié)果 :

     

    SYS

    SYSCAT

    SYSCS_DIAG

    SYSCS_UTIL

    SYSFUN

    SYSIBM

    SYSPROC

    SYSSTAT

     

    Scalar 函數(shù)支持

    一個(gè) scalar 函數(shù)操作預(yù)定義的輸入數(shù)據(jù)集合并返回結(jié)果 . 比如: scalar 函數(shù)調(diào)用 ABS(number) 返回 number 的絕對值 . 這些 scalar 函數(shù)可以作為 SQL 字符串的一部分來使用 . 本版 JDBC 要求當(dāng)所依賴的關(guān)系數(shù)據(jù)庫支持以下功能時(shí): CHAR_LENGTH , CHARACTER_LENGTH , CURRENT_DATE , CURRENT_TIME , CURRENT_TIMESTAMP , EXTRACT , OCTET_LENGTH , POSITION ,驅(qū)動(dòng)必須實(shí)現(xiàn)這些功能。

    Statement , PreparedStatement , CallableStatement

    Statement 接口當(dāng)前提供 isClosed 方法來判斷 statement 是否已關(guān)閉 , setPoolable 用來設(shè)置是否可以被池化 , isPoolable 來檢測當(dāng)前的池化狀態(tài)。

    PreparedStatement CallableStatement 接口現(xiàn)在提供了更多插入大對象的方法 , 通過使用 InputStream Reader .

    Wrapper

    這個(gè)版本的 API 增加了一個(gè)新的 Wrapper 接口, 來提供一種訪問資源的實(shí)例的方法 , 這可能是基于架構(gòu)的考慮 . Wrapper 模式 , 被許多的 JDBC 驅(qū)動(dòng)實(shí)現(xiàn)應(yīng)用以提供 JDBC API 之外的依賴于具體數(shù)據(jù)源的應(yīng)用 . 這個(gè)接口的主要目的是用來提供供應(yīng)商相關(guān)的功能。您可以通過調(diào)用 unwrap 方法來獲取到數(shù)據(jù)庫連接的接口實(shí)現(xiàn)的實(shí)例 . 因?yàn)檫@是一個(gè)重量級的操作 , 在使用前,應(yīng)該先調(diào)用 isWrapperFor 方法來檢測是否當(dāng)前實(shí)例是某種實(shí)現(xiàn)的一個(gè)間接或直接的 Wapper

    能夠給出一個(gè)程序例子當(dāng)然是最好的,但是 Apache Derby 參考手冊 l 指出 : "JDBC 4.0 引入了 wrapped JDBC 對象的概念 ... 對于 Derby 來說 , 這對 Derby 來說是沒有意義的,因?yàn)?/span> Derby 并不做規(guī)范之外的擴(kuò)展 ." 因此看來這種嘗試也就變得無甚必要了 !

    結(jié)論

    我們已經(jīng)分為 4 類討論了 JDBC 4.0 所做的一些改進(jìn)和新的特性,這些新特性增加了編程易用性,提高了生產(chǎn)率 . 盡管 API 規(guī)范已經(jīng)推出幾個(gè)月了 , 到筆者截稿時(shí),主流的數(shù)據(jù)庫廠商都沒有提供本版的 JDBC 驅(qū)動(dòng) . 當(dāng)更多的供應(yīng)商開始支持 JDBC 4.0 時(shí) 當(dāng)然也包括您所中意的那個(gè) 您就可以享受 JDBC4.0 所提供的這些易用的功能了 .

    最后,我認(rèn)為有一個(gè)各大數(shù)據(jù)庫廠商的支持的 JDBC 版本的列表是必要的 . Sun Developer Network (SDN) 上有一個(gè) JDBC Data Access API http://developers.sun.com/product/jdbc/drivers 頁提供了一份更新不太及時(shí)的列表 .
     
    原作者信息:
    Sharad Acharya has more than eight years of experience in the software engineering field in multiple business domains including supply chain, insurance, banking, and mortgage.



     @2008 楊一. 版權(quán)所有. 保留所有權(quán)利

    posted on 2007-04-24 16:25 楊一 閱讀(3379) 評論(2)  編輯  收藏 所屬分類: Java EE

    評論

    # re: [譯]JDBC4.0具有哪些新特性? 2007-05-03 21:56 星泉

    呵呵 長見識了 五一回家剛看了些Java6的特性 回頭做兩個(gè)例子試試傳說中的4.0  回復(fù)  更多評論   

    # re: [譯]JDBC4.0具有哪些新特性? 2008-05-20 16:52 dfdf

    import java.sql.*;
      回復(fù)  更多評論   

    <2007年4月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    293012345

    導(dǎo)航

    公告

    本人在blogjava上發(fā)表的文章及隨筆除特別聲明外均為原創(chuàng)或翻譯,作品受知識產(chǎn)權(quán)法保護(hù)并被授權(quán)遵從 知識分享協(xié)議:署名-非商業(yè)性使用-相同方式共享 歡迎轉(zhuǎn)載,請?jiān)谵D(zhuǎn)載時(shí)注明作者姓名(楊一)及出處(m.tkk7.com/yangyi)
    /////////////////////////////////////////
    我的訪問者

    常用鏈接

    留言簿(5)

    隨筆分類(55)

    隨筆檔案(55)

    相冊

    Java

    其他技術(shù)

    生活

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    自強(qiáng)不息


    用心 - 珍惜時(shí)間,勇于創(chuàng)造
    主站蜘蛛池模板: 亚洲A丁香五香天堂网| 亚洲AV无码久久精品蜜桃| 亚洲网址在线观看你懂的| 亚洲天堂2016| 国产福利免费视频| 91亚洲国产成人精品下载| 亚洲精品无码久久久久久| 两个人看的www免费高清| 国产h视频在线观看免费| 国产性爱在线观看亚洲黄色一级片| 久久精品九九亚洲精品| 免费一级全黄少妇性色生活片| 中文字幕亚洲免费无线观看日本| 免费v片在线观看无遮挡| 亚洲欧洲国产综合| 全部一级一级毛片免费看| 国产电影午夜成年免费视频 | 国内精品免费麻豆网站91麻豆| heyzo亚洲精品日韩| 亚洲av成人综合网| 国产永久免费高清在线| 国产又黄又爽又猛的免费视频播放 | 亚洲av专区无码观看精品天堂| 两性色午夜免费视频| 国产免费拔擦拔擦8x| 亚洲午夜成激人情在线影院| 国产精品免费在线播放| 日本高清免费不卡视频| 亚洲欧洲精品国产区| 国内少妇偷人精品视频免费| 免费国产成人高清视频网站| 亚洲av无码久久忘忧草| 性色午夜视频免费男人的天堂| 亚洲伦乱亚洲h视频| 亚洲人成色在线观看| 免费观看黄色的网站| 久久久久亚洲AV成人无码| 国产免费一级高清淫曰本片| 国产成人青青热久免费精品| 亚洲一区欧洲一区| 日本免费一区二区在线观看|