摘要:
在這篇文章中,我首先將簡要解釋它的繼承層次結構,緊接著,我會使用一個例子演示如何利用Javax.sql.rowset.WebRowSet接口的特征非常容易地將數據庫中的數據轉化為XML文件,或者相反操作。然後我會討論這個接口的利弊。在以上解釋的基礎上,我會總結一些首選這個接口的情況。
任何現實世界中的企業級應用都需要訪問持久化存儲。關系型數據庫管理系統(RDBMS)是使用最廣泛的持久化存儲機制,它支持使用SQL進行數據查詢和更新。JDBC(Java DataBase Connectivity)是一系列的API,這些API為Java程序提供了一個使用SQL查詢和更新RDBMS的框架。
通過Java程序從數據庫中獲取數據或者更新數據庫的過程包含了多個步驟。首先,程序需要建立一個連接,它可以和目標數據庫進行通信。我們可以通過幾種不同的方法建立數據庫連接。傳統的方式是,Java程序在裝載了制造商提供的JDBC驅動後,調用java.sql.DriverManager類中適當的getConnection()方法獲得連接。另外一個(也是首選的)方式是,使用制造商提供的實現或者編寫一個針對目標數據庫的實現了javax.sql.Connection接口的自定義類進行連接對象的初始化。在更多的受約束環境中,例如Java EE容器,提供了使用JNDI(Java Naming and Directory Interface)查找獲得數據庫連接的方式。無論程序使用哪一種方式建立數據庫連接,如果連接成功,它應該有一個對java.sql.Connection接口實例的引用。通過連接,程序創建一個java.sql.Statement實例,或者一個包含數據庫查詢的子接口。最後,程序執行這個語句,獲得一個Java.sql.ResultSet實例,它表示從數據庫中獲得的滿足查詢的實際數據。
在寫這篇文章時,JDK5.0是支持JDBC3.0的Java最新版本。JDBC3.0提供了一些特征,增加了數據操作和轉換的易用性和適應性。
在這篇文章中,我首先將簡要解釋它的繼承層次結構,緊接著,我會使用一個例子演示如何利用Javax.sql.rowset.WebRowSet接口的特征非常容易地將數據庫中的數據轉化為XML文件,或者相反操作。然後我會討論這個接口的利弊。在以上解釋的基礎上,我會總結一些首選這個接口的情況。
版權聲明:任何獲得Matrix授權的網站,轉載時請務必保留以下作者信息和鏈接
作者:Sharad Acharya;mydeman
原文:http://www.onjava.com/pub/a/onJava/2006/06/21/making-most-of-jdbc-with-webrowset.Html
Matrix:http://www.matrix.org.cn/resource/article/44/44626_WebRowSet.Html
關鍵字:WebRowSet;JDBC
WebRowSet層次結構
我們開始先對WebRowSet接口的繼承層次結構作一個簡要的解釋。圖1顯示了相關的Java元素(包、接口和類),它們也是討論的一部分。
繼承層次結構的根部是java.sql.ResultSet接口。這個接口的實例代表表格式的數據,這些數據通過執行包含對底層數據庫查詢的Java.sql.Statement獲取。默認的結果集只能前向遍歷,並且不能更新。你不可能通過遍歷默認結果集的方式進行精確的控制。
那麼,你有哪些選擇呢?這就依賴於你要對結果集進行什麼操作。例如,如果你想結果集支持適合於JavaBeans組件模型的JDBC API,就需要使用java.sql.ResultSet的子接口Javax.sql.RowSet。
因為Java程序訪問數據庫是一個重量級操作,所以內存中的數據高速緩存就是一個關系應用程序性能的關鍵因素。如果你想結果集作為一個行數據的容器緩存在內存中,那麼你可以使用javax.sql.rowset.CachedRowSet,它是Javax.sql.RowSet的子接口。這個接口的實例提供了不用一直保持連接數據源而操作數據的能力。更進一步,它是可滾動、可更新和可序列化的。除數據庫以外,它可以對其它表格式結構的數據源起作用,如電子數據表。
如果除了迄今為止提到的所有特征,你還要將結果集輸出到XML和使用有效的XML作為輸入,請選擇Javax.sql.rowset.WebRowSet.。在Sun的參考實現類中已經提供了它的實例的一個實現,com.sun.rowset.WebRowSetImpl,並作為JDK5.0的一部分發行。
在層次結構的底部是javax.sql.rowset.JoinRowSet,Javax.sql.rowset.WebRowSet的子接口,它提供了聯合多個相關結果集對象的方式,就像對底層數據庫表構造的SQL JOIN。
使用簡單結果集
伴隨上面的介紹給你留下的印象,我向你展示一個簡單的例子。這篇文章的所有例子開發環境都是Eclipse3.1.0,JDK5.0、Windows XP上的Oracle10.2。示例代碼和輸出文件參見資源部分。
我們考慮一個簡單的student表,它定義了四列來存儲信息。接下來的表格顯示了查詢該表獲得的結果。
SQL>select * from student;
ID FNAME LNAME AGE
200 Jack Dakota 21
100 John Doe 26
首先,我們編寫一個Java類,它連接到包含student表的數據庫,並且獲取它的紀錄。
public class DatasourceConnector {
public static void main(String[] args) {
Connection con =null;
OracleDataSource ds =null;
try {
ds = new OracleDataSource();
ds.setUser("");
ds.setPassWord("
");
ds.setURL(
"jdbc:Oracle:thin:@localhost:1521:");
} catch (SQLException e) {
e.printStackTrace();
}
try {
con = ds.getConnection();
Statement stmt = con.createStatement();
ResultSet rs =
stmt.executeQuery(
"select * from student ");
for (int j=0;
j
j++)
{
System.out.print(
rs.getMetaData().
getColumnName(j+1)+"\t");
}
while (rs.next()) {
System.out.print("\n");
for (int i=0;
i< rs.getMetaData().getColumnCount();
i++)
{
System.out.print(
rs.getString(i+1)+"\t");
}
}
rs.close();
stmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
例中的Java類初始化了一個連接對象,創建了一個包含查詢字符串的語句(statement),最後獲取結果。你需要提供數據庫的用戶ID、密碼以及數據庫的SID,在程序中都使用“”標志。保存這個文件為DatasourceConnector.Java,編譯、運行:
>javac DatasourceConnector.Java
>Java DatasourceConnector
應該一切正常,你應該可以看到類似下面的結果:
ID FNAME LNAME AGE
200 Jack Dakota 21
100 John Doe 26
導出結果集
現在我把這個例子更進一步,假定這個程序是一個應用的一部分,應用要求數據從數據庫轉化為XML以進行更進一步地處理。我將使用實現類com.sun.rowset.WebRowSetImpl來完成這個任務。為了實際看到這個結果,我加入一些代碼構造一個Javax.sql.rowset.WebRowSet的實例,並且導出結果集到XML文件。如下所示:
... ... ...
ResultSet rs =
stmt.executeQuery("select * from student");
WebRowSet wrs = new WebRowSetImpl();
wrs.populate(rs);
try {
wrs.writeXML(
new FileOutputStream("student.XML"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
... ... ...
從wrs.writeXML()輸出的結果形成一個符合WebRowSet schema定義的XML文檔。它包含了三部分:屬性、元數據和數據。大致的布局如下所示,完整的輸出文件參見資源部分。
"http://Java.sun.com/XML/ns/jdbc"
XMLns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://Java.sun.com/XML/ns/jdbc
http://Java.sun.com/XML/ns/jdbc/webrowset.xsd">
... ... ...
... ... ...
... ... ...
標簽提供了同步提供者的細節,例如隔離級別(isolation level)、RowSet類型等等。標簽提供了底層數據庫表的信息,例如紀錄數、名稱和列的類型等等。標簽包含了實際數據,上面的表如下所示:
200
Jack
Dakota
21
100
John
Doe
26
上例中的標簽顯示了WebRowSet對象值,當前可以不用任何更改地映射到底層數據源中。任何數據處理操作如插入、更新或刪除都可以在輸出的XML中被恰當的標記出來,我將會在接下來的部分解釋。
操作結果集
你可以刪除一行數據,先移動指針到這一行的位置上,然後調用WebRowSet實例的deleteRow()方法。同樣,你可以更新一個或者多個值,先移動指針到這個行的位置,然後調用合適的更新方法。下面的代碼同時完成了刪除和更新:
... ... ...
ResultSet rs =
stmt.executeQuery("select * from student ");
WebRowSet wrs = new WebRowSetImpl();
wrs.populate(rs);
wrs.absolute(1); //move to first row
wrs.deleteRow(); //delete current row
wrs.absolute(2); //move to second row
wrs.updateInt(4,20);//update current row
... ... ...
前四行代碼片斷的作用是很明顯的:初始化對象並且轉化結果集。接下來的兩行嘗試刪除第一行。最後兩行試圖把第二行紀錄的第四列的值更新為20。輸出這個WebRowSet對象會產生如下的元素:
200
Jack
Dakota
21
100
John
Doe
26
20
這個XML片斷顯示了第一行被標簽標記為刪除。第二行第四列的值被標記出從當前值26更新為一個新值20。
提交更改
迄今為止,我僅僅是操作結果。這些變化並不會反映到底層的數據庫中,除非我進行了提交。下面代碼,如果執行成功,將會通過提交是改變持久。
... ... ...
wrs.acceptChanges();
... ... ...
從XML讀取
WebRowSet也提供了一些readXML()方法,通過使用java.io.InputStream或者Java.io.Reader實例從有效的XML文件中讀取數據。如果你的輸入數據是有效的XML形式,在進行其他處理之前需要將它們持久化到底層的數據庫中,你就會發現這個選項非常有用。
使用WebRowSet的利弊
在展示了WebRowSet的基礎操作之後,我們總結以下使用這種方式操作數據的利弊。
利
+標准方案使它從不同的應用中生成和處理XML數據而不需要轉化成為可能。
+數據操作的易用性――它支持滾動、更新、緩存和離線編輯。
+數據和XML簡單轉化使相關代碼減少。較少的代碼意味著較少的錯誤,也就意味著更加健壯的代碼。
+較少的數據庫更新可以幫助減少並發問題。
弊
+性能和吞吐量可能會因為附加的信息如屬性和元數據受到負面影響。在分布式應用中這可能是一個尤為突出的問題,因為巨大的XML文件需要在網絡上傳輸以充分減少數據的數量。
+新的JDK版本,因為這個特征在1.4或者更老一些的JDK上並不可用。
適用性
WebRowSet接口適合在下面情形中使用:
1、使用XML消息的應用集成,XML消息是當前頂級架構的選擇之一。Java EE應用可以使用基於JMS的集成和其他外部通信,而使用JDBC保存自己的事務狀態。在這樣一個情形下,WebRowSet API減少了編程的復雜性,也降低需要編寫的代碼量。
2、來自持久性數據源的內容展示通常通過獲取數據集並把它傳遞到視圖組件(如JSP)中來完成。一個可用的方式就是在應用XSLT之前把數據集轉化為XML,然後產生展示的內容。這種選擇提供了更好的可維護性,因為它減少來自展示內容的組件的格式化。
總結
直到最近,在數據庫和XML之間來回的數據轉化請求曾經是大部分應用開發和測試資源中一項主要任務。幸運的是,最新的JDBC API包含了一些特點例如數據集的精確導航、數據集的高速緩存、把數據集寫入到XML中等等。對於企業級程序員RDBMS的重要性以及隨著當前不斷增長的Java和XML應用的普及度,像WebRowSet這樣的接口提供的特征將會更加有用。那麼,現在是時候重新考慮一下了,在下一個使用RDBMS作為數據持久化的Java/XML應用中,你是否仍然采用傳統的數據訪問方式;WebRowSet也許可以讓你耳目一新。