Figure 5. Encapsulating the business logic with a POJO façade
表示層調(diào)用POJO facade, POJO facade 調(diào)用業(yè)務(wù)對象。和EJB容器截獲EJB facade方式一樣,AOP通過“攔截機”來截獲POJO facade,并驗證調(diào)用者的權(quán)限,然后開始提交業(yè)務(wù)處理或讓該業(yè)務(wù)循環(huán)等待。
通過在應(yīng)用程序服務(wù)器外部開發(fā)和調(diào)試業(yè)務(wù)邏輯,對POJO facade的開發(fā)可以變的很簡單,同時還可以獲得許多EJB中會話Bean的好處,比如聲明事務(wù)處理和安全。關(guān)鍵是,你可以少寫點代碼。你可以避免寫數(shù)據(jù)傳輸對象類,因為POJO facade可以將對象域直接反饋給表示層;你可以使用依賴注射的方式來將應(yīng)用程序組裝起來,而不用在為JNDI寫查找代碼了。
然而,有些時候不能那用POJO facade,比如它不能參與到遠程客戶端建立的分布式事務(wù)處理。
暴露模型域模式
使用facade的一個缺點是你必須寫額外的代碼,而且負責(zé)將對象域返回給表示層的代碼很容易出錯。如果表示層設(shè)法調(diào)用某個對象,而業(yè)務(wù)層卻沒有提供該對象,也會增加runtime error出現(xiàn)的機會。如果你用JDO , Hibernate或者EJB3,則可以避免這種問題,方法是:將模型域(session區(qū)域)暴露給表示層,再將相應(yīng)的對象域(存儲對象的區(qū)域)返回給表示層,根據(jù)表示層在對象域之間的操作關(guān)系,持久層來導(dǎo)入相應(yīng)的對象。(也就是把session區(qū)域給表示層,然后分析它需要的對象,再讓持久層去加載這些對象)這就是所謂的lazy loading 技術(shù)。
Figure 6. Using an exposed domain model
用這種實現(xiàn)途徑的一個重要的好處是,業(yè)務(wù)層不需要知道哪些對象需要調(diào)用,也不用知道那些需要返回給表示層。盡管這挺起來很簡單,但是你會發(fā)現(xiàn)一些缺點。這會增加表示層的復(fù)雜度,因為你必須處理對數(shù)據(jù)庫的連接。而且在基于Web的應(yīng)用程序中,事務(wù)處理管理也要非常小心,因為在表示層將數(shù)據(jù)反饋給瀏覽器之前,事務(wù)處理的數(shù)據(jù)必須保持正確。
決策3:訪問數(shù)據(jù)庫
無論你怎樣對業(yè)務(wù)邏輯怎樣的組織和封裝,最終你還是要從數(shù)據(jù)庫中取數(shù)據(jù)出來。在經(jīng)典的J2EE應(yīng)用程序中,你有2個選擇:JDBC——這個需要很多的底層代碼;或者實體Bean——這個用起來非常困難,而且缺少重要特征。相比來說,使用輕量級構(gòu)架令人高興的事情之一就是:你有一些新的而且更有力的方法去訪問數(shù)據(jù)庫,而且這種方法可以顯著的減少訪問數(shù)據(jù)庫的代碼。讓咱們來進一步研究。
直接用JDBC會有什么問題
最近突然出現(xiàn)了對象/關(guān)系 映射構(gòu)架(比如JDO和Hibernate) 和SQL映射構(gòu)架(比如iBATIS)這些不是憑空出現(xiàn)的。相反,他們是在JAVA 聯(lián)盟在JDBC屢造挫折之后才出現(xiàn)的。為了了解新構(gòu)架出現(xiàn)的原因,這里咱們回顧一下直接使用JDBC會出現(xiàn)的問題。在許多程序中直接使用JDBC不是一個好的選擇,主要有以下三個原因:。 開發(fā)和維護SQL非常的困難而且耗費時間——一些開發(fā)者發(fā)現(xiàn)要寫龐大而且復(fù)雜的SQL語句非常的困難。反映數(shù)據(jù)庫變化的SQL語句會變得非常耗時。你必須小心的考慮犧牲可維護性是否值得。。 用SQL會使移植性變的很差——因為需要數(shù)據(jù)庫的特殊SQL語句。如果一個程序和多個數(shù)據(jù)庫有關(guān)系,那么你就要寫多個版本的SQL語句,這使得可維護性變變成噩夢。。 直接寫JDBC代碼要會非常耗時,而且容易出錯。你必須寫很多的樣板代碼去獲得連接,創(chuàng)建和初始化適當?shù)穆暶?,還要用精確的聲明去清理連接。而且你還要寫代碼去將JAVA 對象映射到SQL聲明。由于要無奈的去寫,JDBC代碼很容易出錯。
如果你的程序必須直接運行SQL語句的話,那前面兩個問題是無法避免的。有時候為了獲得好的性能,必須要全力的寫SQL語句,包括供應(yīng)商提供的那些特殊東西。由于許多業(yè)務(wù)上的原因,持久層可能會產(chǎn)生混亂的SQL語句,為了防止這種情況,DBA可能要求你的程序來完全控制SQL語句的執(zhí)行。通常,團隊買進的關(guān)系型數(shù)據(jù)庫過于龐大,以至于應(yīng)用程序工作時會出現(xiàn)一些和數(shù)據(jù)庫有關(guān)的瑣碎事務(wù)。根據(jù)“iBATIS in Action”的作者說這里會有一種情況出現(xiàn):“數(shù)據(jù)庫或者SQL語句本身存在的時間比程序代碼存在的時間還要長,或者同一段SQL語句或數(shù)據(jù)庫有多個程序的版本。有些情況下,程序已經(jīng)用另外一種語言重寫了,但是SQL語句和數(shù)據(jù)庫卻沒有太大的改變?!?如果直接使用SQL弄的你筋疲力盡,那么很幸運,這里有一種直接執(zhí)行SQL語句的構(gòu)架,它可比用JDBC要容易多了。當然了,這就是iBATIS.
使用iBATIS
我開發(fā)過的所有企業(yè)JAVA應(yīng)用程序,都是直接執(zhí)行SQL語句的。早期的程序是執(zhí)行特定的SQL語句的,后來是用持久層構(gòu)架再用少量的SQL語句構(gòu)成的。一開始我直接用JDBC來執(zhí)行SQL語句,但是后來,我經(jīng)常寫一些小的構(gòu)架去完成JDBC中那些比較無聊的部分。我也用過一段Spring的JDBC類,這些類除去了JDBC中的許多樣板代碼。但是無論是我自己寫的構(gòu)架還是使用Spring的類,在Java類映射到SQL語句的時候都會存在問題,這就是我為什么那么高興的加入iTATIS 那邊的原因了。
iBATIS 不僅將應(yīng)用程序完全的與“數(shù)據(jù)庫連接”、具體的SQL語句隔絕開來,更實現(xiàn)了通過XML描述文檔來將JavaBean 映射到SQL語句。它用Java bean 內(nèi)省機制來將“道具bean(bean properties)”映射為相應(yīng)的數(shù)據(jù)庫語句占位符,而且它可以將ResultSet后的結(jié)果構(gòu)造為bean.它還可以通過數(shù)據(jù)庫生成主鍵,自動加載相關(guān)的對象、實現(xiàn)緩存和lazy loading.這樣,iBATIS 就除去了許多執(zhí)行SQL語句帶來的苦差。通過編輯XML描述文檔和調(diào)用少量的iBATIS的API,代替了寫大量的JDBC底層代碼。
表示層調(diào)用POJO facade, POJO facade 調(diào)用業(yè)務(wù)對象。和EJB容器截獲EJB facade方式一樣,AOP通過“攔截機”來截獲POJO facade,并驗證調(diào)用者的權(quán)限,然后開始提交業(yè)務(wù)處理或讓該業(yè)務(wù)循環(huán)等待。
通過在應(yīng)用程序服務(wù)器外部開發(fā)和調(diào)試業(yè)務(wù)邏輯,對POJO facade的開發(fā)可以變的很簡單,同時還可以獲得許多EJB中會話Bean的好處,比如聲明事務(wù)處理和安全。關(guān)鍵是,你可以少寫點代碼。你可以避免寫數(shù)據(jù)傳輸對象類,因為POJO facade可以將對象域直接反饋給表示層;你可以使用依賴注射的方式來將應(yīng)用程序組裝起來,而不用在為JNDI寫查找代碼了。
然而,有些時候不能那用POJO facade,比如它不能參與到遠程客戶端建立的分布式事務(wù)處理。
暴露模型域模式
使用facade的一個缺點是你必須寫額外的代碼,而且負責(zé)將對象域返回給表示層的代碼很容易出錯。如果表示層設(shè)法調(diào)用某個對象,而業(yè)務(wù)層卻沒有提供該對象,也會增加runtime error出現(xiàn)的機會。如果你用JDO , Hibernate或者EJB3,則可以避免這種問題,方法是:將模型域(session區(qū)域)暴露給表示層,再將相應(yīng)的對象域(存儲對象的區(qū)域)返回給表示層,根據(jù)表示層在對象域之間的操作關(guān)系,持久層來導(dǎo)入相應(yīng)的對象。(也就是把session區(qū)域給表示層,然后分析它需要的對象,再讓持久層去加載這些對象)這就是所謂的lazy loading 技術(shù)。
Figure 6. Using an exposed domain model
用這種實現(xiàn)途徑的一個重要的好處是,業(yè)務(wù)層不需要知道哪些對象需要調(diào)用,也不用知道那些需要返回給表示層。盡管這挺起來很簡單,但是你會發(fā)現(xiàn)一些缺點。這會增加表示層的復(fù)雜度,因為你必須處理對數(shù)據(jù)庫的連接。而且在基于Web的應(yīng)用程序中,事務(wù)處理管理也要非常小心,因為在表示層將數(shù)據(jù)反饋給瀏覽器之前,事務(wù)處理的數(shù)據(jù)必須保持正確。
決策3:訪問數(shù)據(jù)庫
無論你怎樣對業(yè)務(wù)邏輯怎樣的組織和封裝,最終你還是要從數(shù)據(jù)庫中取數(shù)據(jù)出來。在經(jīng)典的J2EE應(yīng)用程序中,你有2個選擇:JDBC——這個需要很多的底層代碼;或者實體Bean——這個用起來非常困難,而且缺少重要特征。相比來說,使用輕量級構(gòu)架令人高興的事情之一就是:你有一些新的而且更有力的方法去訪問數(shù)據(jù)庫,而且這種方法可以顯著的減少訪問數(shù)據(jù)庫的代碼。讓咱們來進一步研究。
直接用JDBC會有什么問題
最近突然出現(xiàn)了對象/關(guān)系 映射構(gòu)架(比如JDO和Hibernate) 和SQL映射構(gòu)架(比如iBATIS)這些不是憑空出現(xiàn)的。相反,他們是在JAVA 聯(lián)盟在JDBC屢造挫折之后才出現(xiàn)的。為了了解新構(gòu)架出現(xiàn)的原因,這里咱們回顧一下直接使用JDBC會出現(xiàn)的問題。在許多程序中直接使用JDBC不是一個好的選擇,主要有以下三個原因:。 開發(fā)和維護SQL非常的困難而且耗費時間——一些開發(fā)者發(fā)現(xiàn)要寫龐大而且復(fù)雜的SQL語句非常的困難。反映數(shù)據(jù)庫變化的SQL語句會變得非常耗時。你必須小心的考慮犧牲可維護性是否值得。。 用SQL會使移植性變的很差——因為需要數(shù)據(jù)庫的特殊SQL語句。如果一個程序和多個數(shù)據(jù)庫有關(guān)系,那么你就要寫多個版本的SQL語句,這使得可維護性變變成噩夢。。 直接寫JDBC代碼要會非常耗時,而且容易出錯。你必須寫很多的樣板代碼去獲得連接,創(chuàng)建和初始化適當?shù)穆暶?,還要用精確的聲明去清理連接。而且你還要寫代碼去將JAVA 對象映射到SQL聲明。由于要無奈的去寫,JDBC代碼很容易出錯。
如果你的程序必須直接運行SQL語句的話,那前面兩個問題是無法避免的。有時候為了獲得好的性能,必須要全力的寫SQL語句,包括供應(yīng)商提供的那些特殊東西。由于許多業(yè)務(wù)上的原因,持久層可能會產(chǎn)生混亂的SQL語句,為了防止這種情況,DBA可能要求你的程序來完全控制SQL語句的執(zhí)行。通常,團隊買進的關(guān)系型數(shù)據(jù)庫過于龐大,以至于應(yīng)用程序工作時會出現(xiàn)一些和數(shù)據(jù)庫有關(guān)的瑣碎事務(wù)。根據(jù)“iBATIS in Action”的作者說這里會有一種情況出現(xiàn):“數(shù)據(jù)庫或者SQL語句本身存在的時間比程序代碼存在的時間還要長,或者同一段SQL語句或數(shù)據(jù)庫有多個程序的版本。有些情況下,程序已經(jīng)用另外一種語言重寫了,但是SQL語句和數(shù)據(jù)庫卻沒有太大的改變?!?如果直接使用SQL弄的你筋疲力盡,那么很幸運,這里有一種直接執(zhí)行SQL語句的構(gòu)架,它可比用JDBC要容易多了。當然了,這就是iBATIS.
使用iBATIS
我開發(fā)過的所有企業(yè)JAVA應(yīng)用程序,都是直接執(zhí)行SQL語句的。早期的程序是執(zhí)行特定的SQL語句的,后來是用持久層構(gòu)架再用少量的SQL語句構(gòu)成的。一開始我直接用JDBC來執(zhí)行SQL語句,但是后來,我經(jīng)常寫一些小的構(gòu)架去完成JDBC中那些比較無聊的部分。我也用過一段Spring的JDBC類,這些類除去了JDBC中的許多樣板代碼。但是無論是我自己寫的構(gòu)架還是使用Spring的類,在Java類映射到SQL語句的時候都會存在問題,這就是我為什么那么高興的加入iTATIS 那邊的原因了。
iBATIS 不僅將應(yīng)用程序完全的與“數(shù)據(jù)庫連接”、具體的SQL語句隔絕開來,更實現(xiàn)了通過XML描述文檔來將JavaBean 映射到SQL語句。它用Java bean 內(nèi)省機制來將“道具bean(bean properties)”映射為相應(yīng)的數(shù)據(jù)庫語句占位符,而且它可以將ResultSet后的結(jié)果構(gòu)造為bean.它還可以通過數(shù)據(jù)庫生成主鍵,自動加載相關(guān)的對象、實現(xiàn)緩存和lazy loading.這樣,iBATIS 就除去了許多執(zhí)行SQL語句帶來的苦差。通過編輯XML描述文檔和調(diào)用少量的iBATIS的API,代替了寫大量的JDBC底層代碼。