程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 打造更強的Java支持

打造更強的Java支持

編輯:DB2教程

DB2 UDB v.8.2 中 DB2 JDBC Universal Driver 的增強使開發人員得以享受令人驚奇的性能和可管理性。

Linux、Unix 和 Windows 平台上的 DB2 Universal Database (UDB) version 8.2 支持很多類型的 Java 程序,包括在客戶機應用程序、應用程序服務器和 DB2 UDB 服務器中使用的存儲過程或用戶定義函數這兩種形式的程序。

IBM 引入了 DB2 Universal JDBC Driver,以支持 DB2 UDB v.8.1 中的 JDBC 和 SQLJ (用於 Java 應用程序的嵌入式 SQL)編程技術。在 DB2 UDB v.8.2 中,該驅動程序包括對分布式事務、JDBC 3.0 API 以及特定於驅動程序的可服務性和性能增強的完全支持。

DB2 v.8.2 中新的 JDBC 特性包括增強的結果集處理(可保持游標支持)和保存點(savepoint)。在 v.8.2 中,Java 應用程序監控得到很大程度的簡化,因為有了新的可以獲得 DB2 UDB for Linux、Unix 和 Windows 服務器性能信息的 SQL 函數。

我們將向您展示如何開始使用這種新的 JDBC 驅動程序,如何在 Java 應用程序中獲得 DB2 UDB 服務器信息特征,以及如何在開放源代碼開發環境 Eclipse 中構建用於 DB2 的 Java 應用程序。

DB2 UDB v.8.2 包括對很多新 JDBC 3.0 特性的支持,我們無法在此一一闡述。要了解關於 DB2 UDB v.8.2 的 Java 支持的更多信息,請參閱第 32 頁的“Do More With More”以及第 51 頁的 Resources。

Universal JDBC Driver

最新的 Java 編程規范是由 Java 2 Platform Enterprise Edition (J2EE) 1.4 定義的,該規范要求通過一個遵從 JDBC 3.0 的驅動程序來在各種基於 Java 的程序模塊中訪問 RDBMS。這些模塊可能在客戶機工作站上,或者在應用程序服務器中。

DB2 Universal JDBC 驅動程序包括對 Type 4 和 Type 2 模式的連接的支持。在選擇一種 DB2 JDBC 連接模式之前,需要分析開發和運行環境。大多數用戶偏愛“Type 4”驅動程序,因為它可以直接與應用程序一起提供,而不必依賴於共享庫。Type 2 驅動程序總是需要一個共享庫,因為驅動程序和服務器之間的通信是由該驅動程序的非 Java 組件來處理的。根據經驗,如果要經過 TCP/IP 遠程訪問數據庫,那麼應該使用 Type 4;如果與 DB2 服務器(IPC)在同一個邏輯操作系統中,或者在一個 Java 存儲過程中(不能使用 TCP/IP 來訪問 DB2),則應該使用 Type 2。

通過 Java 建立連接

當與 Linux、Unix 和 Windows 上的 DB2 UDB 一起使用 DB2 Universal JDBC Driver 時,必須確保在 DB2 UDB 服務器上支持 TCP/IP 連接。為了確保 DB2 UDB 服務器實例可以接收來自 Java 應用程序的數據庫訪問請求,需要執行兩個步驟:

1. db2set DB2COMM=TCPIP
2. db2 update dbm cfg using SVCENAME <tcp/ip service name>

在 DB2 UDB 服務器安裝期間應該正確地設置這兩項。但是,如果在建立到 DB2 UDB 服務器的初始連接時存在問題,那麼應該首先檢查這兩項設置。SVCENAME 應該與 DB2 UDB 服務器所在計算機上服務文件中定義的端口相對應。

您也許知道,JDBC 是由 Java 2 Standard Edition (J2SE) 規范定義的 DB2 的一個動態 SQL 接口。Java 語言包括很多內建的類和接口,但並沒有提供用於 DB2 UDB 服務器的 JDBC 驅動程序。因此,應用程序需要裝載一組能夠理解如何與 DB2 UDB 服務器交互的類和接口。下面這行 Java 代碼將使用 DB2Driver 接口來完成這個任務:

Class.forName("com.ibm.db2.jcc.DB2Driver")

成功地裝載了驅動程序之後,就可以使用 DriverManager.getConnection 方法連接到 DB2 UDB 服務器,該方法是通過嵌入在 URL 中的 Java 屬性來配置的,該 URL 或者包括在 getConnection() 方法的參數中,或者在一個外部屬性文件中提供。也可以不通過 DriverManager 來建立連接,而是使用可配置的 JDBC 2 數據源實例。

清單 1 展示了用於建立到數據庫的連接的多種技術中的一種。用於連接到 DB2 的 URL 是 jdbc:db2://localhost:50000/sample。DB2 服務器主機名是 localhost,為通信定義的端口是 50000(由 DB2 UDB 服務器的實例配置中的 SVCENAME 定義)。這個連接 URL 表明,應用程序將連接到 SAMPLE 數據庫。清單 1 中的例子要求將一個用戶 ID 和密碼傳遞給數據庫服務器,以便進行認證。連接到數據庫服務器之後,便執行顯式地引用 GHUTCHIS.STAFF 表的 SQL 查詢,並返回結果集。您可以使用列名或列的位置從 JDBC 結果中檢索數據。

清單 1. 用 DB2 Universal JDBC Driver 建立連接

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import Java.sql.Statement;
public class T4DB2Connect {
 public static void main(String[] args) {
 try {
  // load the DB2 Driver
  Class.forName("com.ibm.db2.jcc.DB2Driver");
  // establish a connection to DB2
  Connection db2Conn =
  DriverManager.getConnection(
   "jdbc:db2://localhost:50000/sample",
   "testuser",
   "testpassWord");
  Statement st = db2Conn.createStatement();
  String query =
  "SELECT job, decimal(avg(salary),10,2) "
   + "FROM ghutchis.staff GROUP BY job";
  // execute the query
  ResultSet resultSet = st.executeQuery(query);
  System.out.println("Job " + "\tAverage Salary");
  System.out.println("-----" + "\t--------------");
  while (resultSet.next()) {
  String jobType = resultSet.getString("job");
  double avgSal = resultSet.getDouble(2);
  System.out.println(jobType + "\t" + avgSal);
  }
  resultSet.close();
  st.close();
  db2Conn.close();
 } catch (ClassNotFoundException cnfe) {
  cnfe.printStackTrace();
 } catch (SQLException sqle) {
  sqle.printStackTrace();
 }
 }
}

JDBC 驅動程序包含在 db2jcc.jar 文件中;相應的許可文件是 called db2jcc_license_xxx.jar。在這個例子中,我們將連接到一個 DB2 UDB for Windows 服務器,所以要使用 db2jcc_license_cu.jar 文件。如果您打算將應用程序連接到 DB2 UDB for z/OS,那麼需要 db2jcc_license_cisuz.jar 文件,這個文件是隨 DB2 UDB Connect 和 DB2 UDB Enterprise Server Edition 產品一起提供的。

還可以使用 Java Property 對象來通過 Universal JDBC 驅動程序連接到 DB2 服務器。使用屬性文件(或數據源屬性)的方法使得用於建立連接的細節與應用程序源代碼分離,從而簡化了新 DB2 服務器環境中應用程序的安裝(見清單 2)。

清單 2. 使用 Property 對象連接到 DB2

import Java.util.PropertIEs;
public class T4DB2ConnectProp {
public static void main(String[] args) {
try {
// load the DB2 Driver
Class.forName("com.ibm.db2.jcc.DB2Driver");
// establish a connection to DB2
Properties prop1 = new PropertIEs();
prop1.put("user", "testuser");
prop1.put("password", "testpassWord");
Connection db2Conn =
DriverManager.getConnection(
"jdbc:db2://localhost:50000/sample",
prop1);

用 Eclipse 進行開發

Eclipse 是一種易用的、開放源代碼的集成開發環境(IDE),已成為很多 IBM 軟件產品的基礎,包括 Rational XDE for Java 和 WebSphere Studio Application Developer。我們將向您展示如何使用 Eclipse 2.1 來構建一個簡單的用於 DB2 UDB v.8.2 的 JDBC 應用程序。

為了使用 Eclipse 來構建 DB2 Java 應用程序,首先要創建一個新的 Java 項目。圖 1 展示了如何添加 DB2 Universal JDBC Driver 到項目環境中。

圖 1. 添加 DB2 Universal JDBC Driver 到 Eclipse 中

圖 1. 添加 DB2 Universal JDBC Driver 到 Eclipse 中。

DB2 UDB v.8.2 提供了一組新的 SQL 函數來獲取 DB2 服務器性能信息(在 DB2 UDB v.8.2 的 SQL 參考中有相關文檔)。清單 3 展示了如何收集關於 SQL 查詢在 DB2 UDB 服務器的執行時間的信息。該特性使開發人員可以在開發期間確立查詢性能的基准,而不必使用 DB2 管理工具或第三方的性能工具。

清單 3. 收集 SQL 查詢在 DB2 服務器上的執行時間

with t1 as
(select * from table (snapshot_appl_info('SAMPLE',-1)) as snap_appl_info
where tpmon_clIEnt_app = 'Payroll Module' )
select elapsed_exec_time_ms
from table (snapshot_appl ('SAMPLE',-1)) as snap_appl
where (select agent_id from t1) = snap_appl.agent_id
ELAPSED_EXEC_TIME_MS
--------------------
 77

新的 SQL 管理函數便於跟蹤 Java 應用程序的執行細節。clIEntApplicationInformation 屬性用於幫助確定用於獲得 DB2 UDB 服務器上執行時間的應用程序模塊。清單 3 獲得標識為 Payroll Module 的應用程序的 agent_id,該應用程序連接到 SAMPLE 數據庫。最後一條 SQL 語句的執行時間是 77 毫秒。

現在,讓我們修改這段程序,使之獲得在應用程序中的耗時和在 DB2 UDB 服務器上的執行時間(見清單 4)。下面是一個示例輸出:

Query elapsed time from application: 30 milliseconds.

Total query execution time on DB2 server: 22 milliseconds.

清單 4. 獲得應用程序中的耗時以及 DB2 UDB 服務器上的執行時間

// Access the query execution time on DB2 UDB v.8.2 server
query =
"with t1 as " +
"(select * from table (snapshot_appl_info('SAMPLE',-1)) as "+
"snap_appl_info where tpmon_clIEnt_app = 'Payroll Module') " +
"select integer(elapsed_exec_time_ms)
from table (snapshot_appl ('SAMPLE',-1)) as snap_appl " +
"where (select agent_id from t1) = snap_appl.agent_id";
resultSet = st.executeQuery (query);
while (resultSet.next()){
System.out.println("Total Query execution time on DB2 Stinger: " +
resultSet.getInt(1) + " milliseconds.");
}
resultSet.close();

這些新的 SQL 函數使 Java 開發人員可以清楚地知道,對於任何查詢,網絡傳輸和查詢執行各自所占的比重有多大。請注意,要執行快照 SQL 函數,用戶必須有 DB2 實例上的 SYSCTRL (或更高)權限。

如果在 JDBC 驅動程序處理期間發生錯誤,則 DB2 Universal JDBC Driver 會提供基本的 SQL 異常信息以及 DB2 服務器錯誤細節。現在,讓我們修改應用程序,使之包括打印特定於 DB2 的 DB2Diagnosable 對象的細節。我們還將通過將 currentSchema 設置為一個不存在的數據庫對象來引入一個 SQL 錯誤:

prop1.put("currentSchema","FRED"); // Set unqualifIEd references

圖 5 展示了 DB2 SQLCA 數據結構。對於使用嵌入式 C 的程序員,這種數據結構可能非常面熟。消息標志指出無效的數據庫對象引用(在這個例子中是 FRED.STAFF)。

圖 5. DB2 Universal JDBC Driver 錯誤處理

圖 5. DB2 Universal JDBC Driver 錯誤處理

JDBC 3.0

DB2 UDB v.8.2 引入了對 JDBC 3.0 規范的支持,包括新的結果集保持能力(holdability)和保存點。

可更新的結果集。Java 開發人員更喜歡從 Java API 的角度來思考,而不是從 SQL 的角度去思考。在 JDBC 1.0 中,表示查詢結果的結果集有一個並發類型 CONCUR_READ_ONLY,這意味著結果集不能更新。而在 JDBC 2.0 中具有並發類型 CONCUR_UPDATABLE,這意味著可以使用 Java 代碼、而不是 SQL 來更新結果集。通過 ResultSet 接口的各種 updateXX() 方法可以很方便地更新結果集,這些方法可以更新結果集的內容。程序員可以使用結果集中要更新的列的列索引,或者使用一個表示要更新的列的名稱的字符串。

下面是 updateInt 方法的兩種形式:

updateInt(String columnName, int newIntValue)

updateInt(int columnIndex, int newIntValue)

調用 updateXX 方法更改結果集之後,必須對 ResultSet 對象調用 updateRow 方法,以告知剛才的更新。清單 5 闡釋了可更新結果集的概念。更早的 DB2 附帶的 JDBC 驅動程序(即應用程序驅動程序 — Type 2 — 或網絡驅動程序 — Type 3)要求顯式地通過游標來使用結果集更新數據。清單 5 展示了更常見的(也是我們推薦的)用法。

清單 5. 可更新結果集

String sqlQuery = "select firstName, middleInitial, lastName, from applicants";
ResultSet resultSet = stmt.executeQuery(sqlQuery);
while (resultSet.next())
{
// update the middleInitial column of the applicants table with an "S"
resultSet.updateStringt(2, "S.");
// persist the changes of the result set to the database.
resultSet.updateRow();
}

事務保存點(transaction savepoint)。事務保存點使開發人員可以將更新成組地應用於數據庫。這徹底改變了早期 JDBC 規范中的 all-or-nothing(要麼全做,要麼全不做)方法。事務保存點表示應用程序中的一些標記,必要時您可以根據應用程序邏輯回滾到事務保存點。

要使用這種功能,必須將 Connection 對象的 auto-commit 模式設置為 OFF,這可以通過使用 setAutoCommit 方法,以 false 為參數來完成。定義保存點和回滾在代碼中都不難實現。在清單 6 中,我們將 Connection 對象自治的 AutoCommit 值設置為 false,然後執行兩次更新。接著,我們定義一個名為 SavePoint1 的保存點,再執行兩次更新。當執行接下來的一行 — db2Connection.rollBack(savePoint) — 時,便回滾到前兩次更新後的狀態。

清單 6. 使用事務保存點來回滾更改

// set auto-commit mode to off
db2Connection.setAutoCommit(false);
Statement statement = db2Connection.createStatement();
statement.executeUpdate(firstUpdateStringStatement);
statement.executeUdpate(secondUpdateStringStatemet);
// define a Savepoint marker
Savepoint savePoint = db2Connection.setSavePoint("SavePoint1");
statement.executeUpdate(thirdUpdateStringStatement);
statement.executeUpdate(fourthUpdateStringStatement();
// roll back to the savepoint
db2Connection.rollBack(savePoint);
// commit the changes
db2Connection.commit();

當您想不遵從更改時,這種方式的回滾比較有用。回滾可以結合 Boolean 邏輯,這樣一來便可以設計復雜的業務事務。

游標保持能力。在 JDBC 3.0 之前,當提交事務時,在事務期間創建的任何 ResultSet 對象的游標都將被自動關閉。而對於 JDBC 3.0,您可以撤消這種效果,方法是將 ResultSet.HOLD_CURSORS_OVER_COMMIT 常量提供給 Connection 對象的 createStatement 或 prepareStatement 方法。因此,您可以對結果集中的一組記錄執行一組更新操作,然後將更改提交給 DB2 UDB 服務器。這樣可以將記錄上的 DB2 服務器鎖釋放出來,而使其他應用程序得以看見更改過的數據,並允許應用程序繼續處理 ResultSet。

更多內容

DB2 Universal JDBC Driver 是 DB2 家族中的戰略組成部分,我們只是略微談到 DB2 UDB v.8.2 中的一些 JDBC 增強。在 DB2 UDB 中還可以發現很多的代碼示例,包括完整的 JDBC 驅動程序文檔細節(在“Application Development Guide: Programming ClIEnt Applications”中)。新的基於 Eclipse 技術的 DB2 UDB v.8.2 Information Center 為對 DB2 開發人員和 DB2 管理員有用的信息提供了極好的搜索功能。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved