高级 DAO 编程
在過去 18 個(gè)月中,我參加了一個(gè)由有才華的軟件工程師組成的小組,構(gòu)建定制的、基于 Web 的供應(yīng)鏈管理應(yīng)用程序。我們的應(yīng)用程序訪問范圍廣泛的持久性數(shù)據(jù),包括配送狀態(tài)、供應(yīng)鏈衡量(metrics)、庫(kù)存、貨運(yùn)發(fā)票、項(xiàng)目管理數(shù)據(jù)和用戶信息。我們用 JDBC API 連接到我們公司的不同數(shù)據(jù)庫(kù)平臺(tái)上,并在整個(gè)應(yīng)用程序中使用 DAO 設(shè)計(jì)模式。
圖 1 顯示了應(yīng)用程序和數(shù)據(jù)源之間的關(guān)系:
圖 1. 應(yīng)用程序和數(shù)據(jù)源
在整個(gè)應(yīng)用程序中使用數(shù)據(jù)訪問對(duì)象(DAO)使我們可以將底層數(shù)據(jù)訪問邏輯與業(yè)務(wù)邏輯分離開來。我們構(gòu)建了為每一個(gè)數(shù)據(jù)源提供 GRUD (創(chuàng)建、讀取、更新、刪除)操作的 DAO 類。
在本文中,我將為您介紹構(gòu)建更好的 DAO 類的 DAO 實(shí)現(xiàn)策略和技術(shù)。更確切地說,我將討論日志、異常處理和事務(wù)界定。您將學(xué)到如何將這三者結(jié)合到自己的 DAO 類中。本文假定您熟悉 JDBC API、SQL 和關(guān)系數(shù)據(jù)庫(kù)編程。
我們將以對(duì) DAO 設(shè)計(jì)模式和數(shù)據(jù)訪問對(duì)象的概述開始。
DAO基礎(chǔ)
DAO 模式是標(biāo)準(zhǔn) J2EE 設(shè)計(jì)模式之一。開發(fā)人員用這種模式將底層數(shù)據(jù)訪問操作與高層業(yè)務(wù)邏輯分離開。一個(gè)典型的 DAO 實(shí)現(xiàn)有以下組件:
- 一個(gè) DAO 工廠類
- 一個(gè) DAO 接口
- 一個(gè)實(shí)現(xiàn)了 DAO 接口的具體類
- 數(shù)據(jù)傳輸對(duì)象(有時(shí)稱為值對(duì)象)
具體的 DAO 類包含訪問特定數(shù)據(jù)源的數(shù)據(jù)的邏輯。在下面一節(jié)中您將學(xué)習(xí)設(shè)計(jì)和實(shí)現(xiàn)數(shù)據(jù)訪問對(duì)象的技術(shù)。有關(guān) DAO 設(shè)計(jì)模式的更多內(nèi)容請(qǐng)參閱?參考資料。
回頁(yè)首
事務(wù)界定
關(guān)于 DAO 要記住的重要一點(diǎn)是它們是事務(wù)性對(duì)象。由 DAO 所執(zhí)行的每一個(gè)操作 -- 如創(chuàng)建、更新或者刪除數(shù)據(jù) -- 都與一個(gè)事務(wù)相關(guān)聯(lián)。因此,事務(wù)界定的概念就變得特別重要了。
事務(wù)界定是定義事務(wù)邊界的方式。J2EE 規(guī)范描述了兩種事務(wù)界定的模型:編程式(programmatic)和聲明式(declarative)。表 1 分析了這兩種模型:
表 1. 兩種事務(wù)界定的模型
| 程序員用 EJB 部署描述符聲明事務(wù)屬性。 | 程序員負(fù)責(zé)編寫事務(wù)邏輯。 |
| 運(yùn)行時(shí)環(huán)境(EJB 容器)用這些屬性自動(dòng)管理事務(wù)。 | 應(yīng)用程序通過一個(gè) API 控制事務(wù)。 |
我們將側(cè)重于編程式事務(wù)界定。
設(shè)計(jì)考慮
如前所述,DAO 是事務(wù)性對(duì)象。一個(gè)典型的 DAO 執(zhí)行像創(chuàng)建、更新和刪除這樣的事務(wù)性操作。在設(shè)計(jì) DAO 時(shí),首先要問自己以下問題:
- 事務(wù)要如何開始?
- 事務(wù)應(yīng)如何結(jié)束?
- 哪一個(gè)對(duì)象將負(fù)責(zé)開始一個(gè)事務(wù)?
- 哪一個(gè)對(duì)象將負(fù)責(zé)結(jié)束一個(gè)事務(wù)?
- DAO 是否要負(fù)責(zé)事務(wù)的開始和結(jié)束?
- 應(yīng)用程序是否需要通過多個(gè) DAO 訪問數(shù)據(jù)?
- 事務(wù)涉及到一個(gè) DAO 還是多個(gè) DAO?
- 一個(gè) DAO 是否調(diào)用另一個(gè) DAO 的方法?
了解上述問題的答案將有助于您選擇最適合的 DAO 的事務(wù)界定策略。在 DAO 中有兩種主要的界定事務(wù)的策略。一種方式是讓 DAO 負(fù)責(zé)界定事務(wù),另一種將事務(wù)界定交給調(diào)用這個(gè) DAO 方法的對(duì)象處理。如果選擇了前一種方式,那么就將事務(wù)代碼嵌入到 DAO 中。如果選擇后一種方式,那么事務(wù)界定代碼就是在 DAO 類外面。我們將使用簡(jiǎn)單的代碼示例幫助您更好理解每一種方式是如何工作的。
清單 1 顯示了一個(gè)有兩種數(shù)據(jù)操作的 DAO:創(chuàng)建和更新:
清單 1. DAO 方法
public void createWarehouseProfile(WHProfile profile);public void updateWarehouseStatus(WHIdentifier id, StatusInfo status);清單 2 顯示了一個(gè)簡(jiǎn)單的事務(wù)。事務(wù)界定在 DAO 類外面。注意在這個(gè)例子中調(diào)用者是如何在一個(gè)事務(wù)中結(jié)合多個(gè) DAO 操作的。
清單 2. 調(diào)用者管理的事務(wù)
tx.begin(); // start the transactiondao.createWarehouseProfile(profile);dao.updateWarehouseStatus(id1, status1);dao.updateWarehouseStatus(id2, status2);tx.commit(); // end the transaction這種事務(wù)界定策略對(duì)于需要在一個(gè)事務(wù)中訪問多個(gè) DAO 的應(yīng)用程序特別有用。
可以用 JDBC API 或者 Java 事務(wù) API(Java Transaction API JTA)實(shí)現(xiàn)事務(wù)界定。 JDBC 事務(wù)界定比 JTA 事務(wù)界定要簡(jiǎn)單,但是 JTA 提供了更多的靈活性。在下面一節(jié)中我將更深入地分析事務(wù)界定的機(jī)制。
回頁(yè)首
用 JDBC 進(jìn)行事務(wù)界定
JDBC 事務(wù)是用?Connection?對(duì)象控制的。JDBC Connection 接口(?java.sql.Connection?)提供了兩種事務(wù)模式:自動(dòng)提交和手工提交。java.sql.Connection?提供了以下控制事務(wù)的方法:
- public void setAutoCommit(boolean)
- public boolean getAutoCommit()
- public void commit()
- public void rollback()
清單 3 顯示了如何用 JDBC API 界定一個(gè)事務(wù):
清單 3. 用 JDBC API 進(jìn)行事務(wù)界定
import java.sql.*;import javax.sql.*;// ...DataSource ds = obtainDataSource();Connection conn = ds.getConnection();conn.setAutoCommit(false);// ...pstmt = conn.prepareStatement("UPDATE MOVIES ...");pstmt.setString(1, "The Great Escape");pstmt.executeUpdate();// ...conn.commit();// ...使用 JDBC 事務(wù)界定時(shí),您可以將多個(gè) SQL 語(yǔ)句結(jié)合到一個(gè)事務(wù)中。JDBC 事務(wù)的一個(gè)缺點(diǎn)是事務(wù)的范圍局限于一個(gè)數(shù)據(jù)庫(kù)連接。一個(gè) JDBC 事務(wù)不能跨越多個(gè)數(shù)據(jù)庫(kù)。在下面,我們將看一下如何用 JTA 進(jìn)行事務(wù)界定。因?yàn)?JTA 不像 JDBC 那樣有名,所以我們首先做一個(gè)簡(jiǎn)介。
回頁(yè)首
JTA簡(jiǎn)介
Java 事務(wù) API(JTA) 及其同門兄弟 Java 事務(wù)服務(wù)(Java Transaction Service JTS)為 J2EE 平臺(tái)提供了分布式事務(wù)服務(wù)。一個(gè)?分布式的事務(wù)涉及一個(gè)事務(wù)管理器和一個(gè)或者多個(gè)資源管理器。一個(gè)?資源管理器是任何類型的持久性的數(shù)據(jù)存儲(chǔ)。事務(wù)管理器負(fù)責(zé)協(xié)調(diào)所有事務(wù)參與者之間的通信。事務(wù)管理器與資源管理器之間的關(guān)系如圖 2 所示:
圖 2. 一個(gè)事務(wù)管理器和資源管理器
JTA 事務(wù)比 JDBC 事務(wù)功能更強(qiáng)。JDBC 事務(wù)局限為一個(gè)數(shù)據(jù)庫(kù)連接,而 JTA 事務(wù)可以有多個(gè)參與者。所有下列 Java 平臺(tái)組件都可以參與 JTA 事務(wù):
- JDBC 連接
- JDO?PersistenceManager?對(duì)象
- JMS 隊(duì)列
- JMS 主題
- 企業(yè) JavaBeans
- 符合 J2EE 連接體系結(jié)構(gòu)(J2EE Connector Architecture)規(guī)范的資源適配器
回頁(yè)首
使用 JTA 的事務(wù)界定
要用 JTA 進(jìn)行事務(wù)界定,應(yīng)用程序要調(diào)用?javax.transaction.UserTransaction?接口中的方法。清單 4 顯示了對(duì)?UserTransaction對(duì)象的典型 JNDI 查詢:
清單 4. 一個(gè)對(duì) UserTransaction 對(duì)象的 JDNI 查詢
import javax.transaction.*;import javax.naming.*;// ...InitialContext ctx = new InitialContext();Object txObj = ctx.lookup("java:comp/UserTransaction");UserTransaction utx = (UserTransaction) txObj;當(dāng)應(yīng)用程序找到了?UserTransaction?對(duì)象后,就可以開始事務(wù)了,如清單 5 所示:
清單 5. 用 JTA 開始一個(gè)事務(wù)
utx.begin();// ...DataSource ds = obtainXADataSource();Connection conn = ds.getConnection();pstmt = conn.prepareStatement("UPDATE MOVIES ...");pstmt.setString(1, "Spinal Tap");pstmt.executeUpdate();// ...utx.commit();// ...當(dāng)應(yīng)用程序調(diào)用?commit()?時(shí),事務(wù)管理器用一個(gè)兩階段的提交協(xié)議結(jié)束事務(wù)。
回頁(yè)首
控制事務(wù)的 JTA 方法
javax.transaction.UserTransaction?接口提供了以下事務(wù)控制方法:
- public void begin()
- public void commit()
- public void rollback()
- public int getStatus()
- public void setRollbackOnly()
- public void setTransactionTimeout(int)
應(yīng)用程序調(diào)用?begin()?開始事務(wù)。應(yīng)用程序調(diào)用?commit()?或者?rollback()?結(jié)束事務(wù)。參閱?參考資料以了解更多關(guān)于用 JTA 進(jìn)行事務(wù)管理的內(nèi)容。
回頁(yè)首
使用 JTA 和 JDBC
開發(fā)人員通常在 DAO 類中用 JDBC 進(jìn)行底層數(shù)據(jù)操作。如果計(jì)劃用 JTA 界定事務(wù),那么就需要有一個(gè)實(shí)現(xiàn)?javax.sql.XADataSource?、javax.sql.XAConnection?和?javax.sql.XAResource?接口的 JDBC 驅(qū)動(dòng)程序。一個(gè)實(shí)現(xiàn)了這些接口的驅(qū)動(dòng)程序?qū)⒖梢詤⑴c JTA 事務(wù)。一個(gè)?XADataSource?對(duì)象就是一個(gè)?XAConnection?對(duì)象的工廠。?XAConnection?s 是參與 JTA 事務(wù)的 JDBC 連接。
您將需要用應(yīng)用服務(wù)器的管理工具設(shè)置?XADataSource?。從應(yīng)用服務(wù)器和 JDBC 驅(qū)動(dòng)程序的文檔中可以了解到相關(guān)的指導(dǎo)。
J2EE 應(yīng)用程序用 JNDI 查詢數(shù)據(jù)源。一旦應(yīng)用程序找到了數(shù)據(jù)源對(duì)象,它就調(diào)用?javax.sql.DataSource.getConnection()?以獲得到數(shù)據(jù)庫(kù)的連接。
XA 連接與非 XA 連接不同。一定要記住 XA 連接參與了 JTA 事務(wù)。這意味著 XA 連接不支持 JDBC 的自動(dòng)提交功能。同時(shí),應(yīng)用程序一定不要對(duì) XA 連接調(diào)用?java.sql.Connection.commit()?或者?java.sql.Connection.rollback()?。相反,應(yīng)用程序應(yīng)該使用UserTransaction.begin()、UserTransaction.commit()?和?serTransaction.rollback()?。
回頁(yè)首
選擇最好的方式
我們討論了如何用 JDBC 和 JTA 界定事務(wù)。每一種方式都有其優(yōu)點(diǎn),您需要決定哪一種最適合于您的應(yīng)用程序。
在最近的許多項(xiàng)目中,我們小組是用 JDBC API 進(jìn)事務(wù)界定來構(gòu)建 DAO 類的。這些 DAO 類可以總結(jié)如下:
- 事務(wù)界定代碼嵌入在 DAO 類中。
- DAO 類使用 JDBC API 進(jìn)行事務(wù)界定。
- 調(diào)用者不能界定事務(wù)。
- 事務(wù)范圍局限于單個(gè) JDBC 連接。
JDBC 事務(wù)并不總是適合復(fù)雜的企業(yè)應(yīng)用程序。如果您的事務(wù)要跨越多個(gè) DAO 或者多個(gè)數(shù)據(jù)庫(kù),那么下列實(shí)現(xiàn)策略也許更合適:
- 事務(wù)用 JTA 界定。
- 事務(wù)界定代碼從 DAO 中分離出來。
- 調(diào)用者負(fù)責(zé)界定事務(wù)。
- DAO 加入一個(gè)全局事務(wù)。
JDBC 方式由于其簡(jiǎn)單性而具有吸引力,JTA 方式提供了更大的靈活性。您所選擇的實(shí)現(xiàn)將取決于應(yīng)用程序的特定需求。
回頁(yè)首
日志記錄和 DAO
一個(gè)良好實(shí)現(xiàn)的 DAO 類將使用日志記錄來捕捉有關(guān)其運(yùn)行時(shí)行為的細(xì)節(jié)。您可以選擇記錄異常、配置信息、連接狀態(tài)、JDBC 驅(qū)動(dòng)程序元數(shù)據(jù)、或者查詢參數(shù)。日志對(duì)于開發(fā)的所有階段都很有用。我經(jīng)常在開發(fā)時(shí)、測(cè)試時(shí)和生產(chǎn)中分析應(yīng)用程序日志。
在本節(jié),我將展示一個(gè)顯示如何將 Jakarta Commons Logging 加入到 DAO 中的代碼示例。在這之前,讓我們回顧一下一些基本知識(shí)。
選擇日志庫(kù)
許多開發(fā)人員使用一種原始格式進(jìn)行日志記錄:?System.out.println?和?System.err.println?。?Println?語(yǔ)句速度快且使用方便,但是它們沒有提供全功能的日志記錄系統(tǒng)所具有的功能。表 2 列出了 Java 平臺(tái)的日志庫(kù):
表 2. Java 平臺(tái)的日志庫(kù)
| java.util.logging | 不是 | http://java.sun.com/j2se/ |
| Jakarta Log4j | 是 | http://jakarta.apache.org/log4j/ |
| Jakarta Commons Logging | 是 | http://jakarta.apache.org/commons/logging.html |
Jakarta Commons Logging 可以與?java.util.logging?或者 Jakarta Log4j 一同使用。Commons Logging 是一個(gè)日志抽象層,它隔離了應(yīng)用程序與底層日志實(shí)現(xiàn)。使用 Commons Logging,您可以通過改變配置文件更換底層日志實(shí)現(xiàn)。Commons Logging 在 Jakarta Struts 1.1 和 Jakarta HttpClient 2.0 中使用。
一個(gè)日志記錄示例
清單 7 顯示了如何在 DAO 類中使用 Jakarta Commons Logging:
清單 7. DAO 類中的 Jakarta Commons Logging
import org.apache.commons.logging.*; class DocumentDAOImpl implements DocumentDAO {static private final Log log = LogFactory.getLog(DocumentDAOImpl.class);public void deleteDocument(String id){// ...log.debug("deleting document: " + id);// ...try{// ... data operations ...}catch (SomeException ex){log.error("Unable to delete document", ex);// ... handle the exception ...}} }日志記錄是所有任務(wù)關(guān)鍵型應(yīng)用程序的重要部分。如果在 DAO 中遇到故障,那么日志通常可以提供判斷出錯(cuò)位置的最好信息。將日志加入到 DAO 可以保證您有機(jī)會(huì)進(jìn)行調(diào)試和故障排除。
回頁(yè)首
DAO 中的異常處理
我們討論過了事務(wù)界定和日志,現(xiàn)在對(duì)于如何在數(shù)據(jù)訪問對(duì)象上應(yīng)用它們有了更深入的理解。我們的第三個(gè)和最后一個(gè)討論議題是異常處理。遵從幾個(gè)簡(jiǎn)單的異常處理指導(dǎo)可以使您的 DAO 更容易使用、更健壯及更易于維護(hù)。
在實(shí)現(xiàn) DAO 模式時(shí),考慮以下問題:
- DAO 的公共接口中的方法是否拋出檢查過的異常?
- 如果是的話,拋出何種檢查過的異常?
- 在 DAO 實(shí)現(xiàn)類中如何處理異常?
在使用 DAO 模式的過程中,我們的小組開發(fā)了一些處理異常的原則。遵從這些原則可以極大地改進(jìn)您的 DAO:
- DAO 方法應(yīng)該拋出有意義的異常。
- DAO 方法不應(yīng)該拋出?java.lang.Exception?。?java.lang.Exception?太一般化了。它不傳遞關(guān)于底層問題的任何信息。
- DAO 方法不應(yīng)該拋出?java.sql.SQLException?。SQLException 是一個(gè)低級(jí)別的 JDBC 異常。一個(gè) DAO 應(yīng)該力爭(zhēng)封裝 JDBC 而不是將 JDBC 公開給應(yīng)用程序的其余部分。
- 只有在可以合理地預(yù)期調(diào)用者可以處理異常時(shí),DAO 接口中的方法才應(yīng)該拋出檢查過的異常。如果調(diào)用者不能以有意義的方式處理這個(gè)異常,那么考慮拋出一個(gè)未檢查的(運(yùn)行時(shí))異常。
- 如果數(shù)據(jù)訪問代碼捕獲了一個(gè)異常,不要忽略它。忽略捕獲的異常的 DAO 是很難進(jìn)行故障診斷的。
- 使用鏈接的異常將低級(jí)別的異常轉(zhuǎn)化為高級(jí)別的異常。
- 考慮定義標(biāo)準(zhǔn) DAO 異常類。Spring Framework (參閱?參考資料)提供了很好的一套預(yù)定義的 DAO 異常類。
有關(guān)異常和異常處理技術(shù)的更多信息參閱?參考資料。
回頁(yè)首
實(shí)現(xiàn)實(shí)例: MovieDAO
MovieDAO?是一個(gè)展示本文中討論的所有技術(shù)的 DAO:事務(wù)界定、日志和異常處理。您可以在?參考資料一節(jié)中找到?MovieDAO?源代碼。代碼分為三個(gè)包:
- daoexamples.exception
- daoexamples.movie
- daoexamples.moviedemo
DAO 模式的這個(gè)實(shí)現(xiàn)包含下面列出的類和接口:
- daoexamples.movie.MovieDAOFactory
- daoexamples.movie.MovieDAO
- daoexamples.movie.MovieDAOImpl
- daoexamples.movie.MovieDAOImplJTA
- daoexamples.movie.Movie
- daoexamples.movie.MovieImpl
- daoexamples.movie.MovieNotFoundException
- daoexamples.movie.MovieUtil
MovieDAO?接口定義了 DAO 的數(shù)據(jù)操作。這個(gè)接口有五個(gè)方法,如下所示:
- public Movie findMovieById(String id)
- public java.util.Collection findMoviesByYear(String year)
- public void deleteMovie(String id)
- public Movie createMovie(String rating, String year, String, title)
- public void updateMovie(String id, String rating, String year, String title)
daoexamples.movie?包包含?MovieDAO?接口的兩個(gè)實(shí)現(xiàn)。每一個(gè)實(shí)現(xiàn)使用一種不同的方式進(jìn)行事務(wù)界定,如表 3 所示:
表 3. MovieDAO 實(shí)現(xiàn)
| 實(shí)現(xiàn) MovieDAO 接口? | 是 | 是 |
| 通過 JNDI 獲得 DataSource? | 是 | 是 |
| 從 DataSource 獲得 java.sql.Connection 對(duì)象? | 是 | 是 |
| DAO 在內(nèi)部界定事務(wù)? | 是 | 否 |
| 使用 JDBC 事務(wù)? | 是 | 否 |
| 使用一個(gè) XA DataSource? | 否 | 是 |
| 參與 JTA 事務(wù)? | 否 | 是 |
MovieDAO 演示應(yīng)用程序
這個(gè)演示應(yīng)用程序是一個(gè)名為?daoexamples.moviedemo.DemoServlet?的 servlet 類。?DemoServlet?使用這兩個(gè) Movie DAO 查詢和更新表中的電影數(shù)據(jù)。
這個(gè) servlet 展示了如何將支持 JTA 的?MovieDAO?和 Java 消息服務(wù)(Java Message Service)結(jié)合到一個(gè)事務(wù)中,如清單 8 所示。
清單 8. 將 MovieDAO 和 JMS 代碼結(jié)合到一個(gè)事務(wù)中
UserTransaction utx = MovieUtil.getUserTransaction();utx.begin();batman = dao.createMovie("R","2008","Batman Reloaded");publisher = new MessagePublisher();publisher.publishTextMessage("I'll be back");dao.updateMovie(topgun.getId(),"PG-13",topgun.getReleaseYear(),topgun.getTitle());dao.deleteMovie(legallyblonde.getId());utx.commit();要運(yùn)行這個(gè)演示應(yīng)用程序,需要在應(yīng)用服務(wù)器上配置一個(gè) XA 數(shù)據(jù)源和一個(gè)非 XA 數(shù)據(jù)源。然后,部署 daoexamples.ear 文件。這個(gè)應(yīng)用程序可以在任何兼容 J2EE 1.3 的應(yīng)用服務(wù)器上運(yùn)行。參閱?參考資料以獲得 EAR 文件和源代碼。
回頁(yè)首
結(jié)束語(yǔ)
正如本文所展示的,實(shí)現(xiàn) DAO 模式需要做比編寫低級(jí)別的數(shù)據(jù)訪問代碼更多的工作。現(xiàn)在,通過選擇一個(gè)適合您的應(yīng)用程序的事務(wù)界定策略、通過在 DAO 類中加入日志記錄,以及通過遵從幾項(xiàng)簡(jiǎn)單的異常處理原則,您可以構(gòu)建更好的 DAO。
參考資料
- 您可以參閱本文在 developerWorks 全球站點(diǎn)上的?英文原文.
- 從?daoexamples.sourceforge.net上下載 MovieDAO 源代碼。
- 想要學(xué)習(xí)有關(guān)數(shù)據(jù)訪問對(duì)象模式的更多內(nèi)容?可以從?核心 J2EE 模式主頁(yè)開始。
- Kyle Brown 的“?A stepped approach to J2EE testing with SDAO”(?developerWorks,2003 年 3 月)提供了對(duì)數(shù)據(jù)訪問對(duì)象和 DAO 設(shè)計(jì)模式的簡(jiǎn)要介紹。
- Dragonslayer 的教程“?Create persistent application data with Java Data Objects”(developerWorks,2003 年 7 月)向您展示了如何結(jié)合 Struts 與 DAO 模式以用于影響小的企業(yè)數(shù)據(jù)持久性。
- Srikanth Shenoy 的“?EJB 異常處理的最佳做法”(?developerWorks,2002 年 5 月)介紹了異常處理基礎(chǔ)和使用 Log4J 進(jìn)行日志記錄。
- Java 理論與實(shí)踐系列從“?理解 JTS -- 事務(wù)處理簡(jiǎn)介”開始(?developerWorks,2002年3月)提供了對(duì) Java 事務(wù) API 的三部分介紹。
- Java Transaction API是 J2EE 平臺(tái)的關(guān)鍵部分。
- Jakarta Log4j是 Java 應(yīng)用程序的世界級(jí)日志庫(kù)。
- Jakarta Commons Logging提供了容易使用的日志抽象層。
- Spring Framework為 JDBC 和事務(wù)管理提供了抽象層。此外,這個(gè)框架包含標(biāo)準(zhǔn)的 DAO 異常類和 JNDI 幫助器類。
- Rod Johnson 的?J2EE Design and Development(Wrox Press,2002 年)是每一位 J2EE 開發(fā)人員都應(yīng)該收藏的。本書充滿了應(yīng)用程序設(shè)計(jì)策略、實(shí)用編程技巧和實(shí)際的例子。
- Josh Bloch 的?Effective Java Programming Language Guide?(Addison Wesley,2001 年)展示了異常處理和類庫(kù)設(shè)計(jì)的最佳實(shí)踐。
- 參閱 Java 技術(shù)專區(qū)的教程頁(yè)面,從?developerWorks?獲得免費(fèi)的?Java 技術(shù)教程的完整列表。
- 在?developerWorks?Java 技術(shù)專區(qū)?中可以找到數(shù)百篇關(guān)于 Java 編程的各個(gè)方面的文章。
總結(jié)
- 上一篇: 涨姿势!北京地铁原来是16条旅游专线
- 下一篇: 我的VIM配置及说明【K-VIM】