好學驛站

          JSP、JAVA、struts、hibernate、spring、eclipse、工作流、電子政務、協(xié)同辦公、J2ME

          Java 項目中應用Subversion配置與管理(轉(zhuǎn))

          Java 企業(yè)級項目中應用Subversion的配置與管理
          --JavaSVN + Subversion跟蹤數(shù)據(jù)變化歷史

          譯者:陳海青(http://www.chq.name)

          ??? 企業(yè)最重要的資產(chǎn)應該是數(shù)據(jù)信息,但現(xiàn)在的企業(yè)應用除了需要存儲數(shù)據(jù)外,還經(jīng)常要求跟蹤數(shù)據(jù)變化整個過程,并會擴展到一系列相關(guān)的要求,如數(shù)據(jù)變化的原因、變化的時間等,而且在許多情況下是對以文檔形式存儲的數(shù)據(jù)進行跟蹤。使用SubVersion可以滿足這些貌似普通但實際上很復雜的要求

          版權(quán)聲明:任何獲得Matrix授權(quán)的網(wǎng)站,轉(zhuǎn)載時請務必保留以下作者信息和鏈接
          作者:陳海青(http://www.chq.name);michaelzyy
          原文:http://www.matrix.org.cn/resource/article/2007-02-05/Subversion_ba84f1b9-b4b0-11db-b1a9-1f2330fc56f8.html
          關(guān)鍵字:Java;Subversion

          來自數(shù)據(jù)的挑戰(zhàn)

          ??? 企業(yè)應用存儲了關(guān)鍵數(shù)據(jù),而且應用程序并不僅限于對數(shù)據(jù)進行插入、讀取、更新和刪除操作(即CRUD),應用程序還期望能夠存儲數(shù)據(jù)更改的歷史記錄。此外,企業(yè)按照一系列的業(yè)務或者規(guī)定的要求,不但要求存儲數(shù)據(jù)資產(chǎn)更改結(jié)果的歷史,而且要求存儲是誰,在什么時候,因為什么原因,如何改變了數(shù)據(jù)等等諸如此類的跟蹤信息。

          ??? 應用數(shù)據(jù)的形式和尺寸也有很多變數(shù),既有簡單數(shù)據(jù),如字符串和數(shù)字型,也有復雜的類型,如使用Blob或Cblob類型來存儲文檔。典型的應用程序要處理大量的上傳給程序處理的以文檔形式存儲的數(shù)據(jù),如果用傳統(tǒng)的歷史表等方式來跟蹤諸如復雜類型的文檔的變化,簡直就是做一場惡夢。

          使用歷史表進行跟蹤

          ??? 關(guān)系數(shù)據(jù)庫是存儲數(shù)據(jù)的首選,可以高效地組織、存儲、檢索數(shù)據(jù)信息,由于應用程序?qū)?shù)據(jù)存放在關(guān)系數(shù)據(jù)庫中,當然就順理成章的嘗試用它來存放歷史跟蹤數(shù)據(jù),一般是使用帶有時間戳的數(shù)據(jù)表來存放所有的重要數(shù)據(jù)表。在更新主表的時候會把舊數(shù)據(jù)推入歷史表中,這個過程一般是通過觸發(fā)器或由應用程序自己來完成。

          使用歷史表存儲歷史信息,會存在以下問題:
          +關(guān)系型數(shù)據(jù)庫和關(guān)系模型會提高數(shù)據(jù)存儲和檢索的效率,但是歷史表顯然不適合使用關(guān)系型數(shù)據(jù)庫。
          +數(shù)據(jù)庫不支持版本控制。應用程序不得不使用觸發(fā)器或其它定制的技術(shù)來仔細的存放數(shù)據(jù)(,以便實現(xiàn)版本控制功能)。
          +必須由應用程序親自檢測版本之間的變化,從歷史表中檢索歷史數(shù)據(jù)進行互相比較。

          ??? 關(guān)系數(shù)據(jù)庫依舊是存儲和檢索業(yè)務數(shù)據(jù)的倉庫,它們擅長于管理數(shù)據(jù)。以上列舉的缺點僅限于用關(guān)系數(shù)據(jù)模型存儲多個不同的版本的數(shù)據(jù)并進行歷史數(shù)據(jù)跟蹤的情況下。

          Subversion 和 JavaSVN

          ??? Subversion是一個可以代替CVS(一個傳統(tǒng)的版本控制系統(tǒng))的版本控制系統(tǒng)。Subversion使用稱作倉庫的樹狀結(jié)構(gòu)來存儲文件和目錄。Subversion會跟蹤對倉庫中信息的所有改變,它具有一個中央倉庫,允許進行并發(fā)更新,允許通過http或https使用WebDAV協(xié)議來訪問倉庫,可以避免使用過程中的防火墻的干擾。Subversion的理念就是“拷貝-編輯-合并”,這就意味著在修改時不需要鎖定被修改的對象。

          ??? (譯者注:關(guān)于WebDAV,是Web-based Distributed Authoring and Versioning的縮寫,是一個標準HTTP協(xié)議的擴展,通過web技術(shù)把目錄和文件作為可讀些的對象進行共享讀寫,把web變成一個可讀寫的媒體。RFCs2518和3253描述了WebDAV/DeltaV 對于HTTP的擴展,網(wǎng)址http://www.webdav.org/。)

          ??? JavaSVN是一個純Java的Subversion客戶端類庫,提供與Subversion交互的基于Java程序的應用程序接口(API), JavaSVN既提供了進行直接讀取Subversion倉庫的底層接口,也提供了從Subversion倉庫檢出工作拷貝的高層接口。

          ??? 現(xiàn)在,應用程序可以使用結(jié)合了關(guān)系型數(shù)據(jù)庫和Subversion的方式來滿足數(shù)據(jù)存儲和變化跟蹤的需求了,對數(shù)據(jù)庫的更新同時會將變化情況提交到Subversion中,Subversion將是記錄變化的主要數(shù)據(jù)源,關(guān)系數(shù)據(jù)庫則用于除此以外所有的其他存儲。這樣做還有一個優(yōu)勢,由于Subversion使用“拷貝-編輯-合并”模式,這樣每次從關(guān)系數(shù)據(jù)庫中檢索數(shù)據(jù)時不再要求鎖定目標表了。

          實例學習

          ??? 現(xiàn)在讓我們來確定一下要解決的問題和解決方案,并使用實例來說明如何使用Subversion 和JavaSVN。我們使用JavaSVN將一個簡單的領域?qū)ο蟠鎯Φ絊ubversion 中,檢索以前的版本,并顯示兩個版本的差異。我們示例的領域?qū)ο笫且韵滤镜馁J款數(shù)據(jù)。在本文結(jié)尾的“資源”部分有完整的源代碼鏈接。

          public class LoanData extends BaseTrackingObject {
          ????????private String loanId;
          ????????private double loanAmount;
          ????????private float??loanRate;
          ????????private int????loanTerm;
          ????????......
          ????????......
          }



          ??? 在這里,使用抽象的BaseTrackingObject類來定義通用的跟蹤數(shù)據(jù),如修改用戶、修改日期、修改原因等。其中定義了設置和取得objectId抽象方法,把它用作主鍵來訪問領域?qū)ο螅欢x了一個命名為getXmlRepresentation的工具方法,用于把對象轉(zhuǎn)換成XML格式,進而用于在Subversion中存儲和檢索數(shù)據(jù)。

          初始化JavaSVN

          ??? SVNManager類是通向Subversion的路由,用于在不使用工作拷貝的情況下,通過底層JavaSVN接口直接訪問Subversion倉庫,通過初始化JavaSVN類庫來可以使用HTTP(S)或SVN(S)與Subversion倉庫進行交互。在這里,我們選擇使用HTTP (WebDAV),因為可以減少在處理防火墻方面的工作。

          ??? 庫的初始化工作要首先調(diào)用的是方法DAVRepositoryFactory.setup()。SVNRepository類包含了所有直接訪問Subversion倉庫的方法,將Subversion倉庫樹狀結(jié)構(gòu)的根路徑提供給SVNRepositoryFactory類后,就完成了這個類的初始化,而ISVNAuthenticationManager類的作用是向SVNRepository提供訪問Subversion倉庫的授權(quán)信息。

          public void initRepository() {
          ????????//initialize the system to work over http
          ????????DAVRepositoryFactory.setup();
          ????????............
          ????????//point to the root folder of repository
          ????????SVNURL svnUrl = SVNURL.parseURIEncoded
          ????????????????????????("http://localhost/repos/");
          ????????//initialize the SVNRepository
          ????????theRepository = SVNRepositoryFactory.
          ????????????????????????create(svnUrl);
          ????????//Creates the Auth manager with our user
          ????????//and password credentials
          ????????ISVNAuthenticationManager authManager =
          ????????????????new BasicAuthenticationManager
          ????????????????(name, password);
          ????????//provides the credentials to the
          ????????//SVNRepository
          ????????theManager.setAuthenticationManager
          ????????????????(authManager);
          ????????........
          }

          在Subversion中存儲數(shù)據(jù)

          ??? Subversion需要使用層次結(jié)構(gòu)存儲數(shù)據(jù),這樣我們先要設定一下領域?qū)嶓w的層次結(jié)構(gòu),這里使用一個命名為“DomainObjects”的文件夾來存放領域數(shù)據(jù)。領域?qū)ο箢悓z測這個目錄下存放領域?qū)ο蟮乃凶幽夸洠總€獨立的域?qū)ο蟊灰訶ML格式進行存儲,并以其主鍵進行命名。

          ??? 為存儲LoanData域?qū)ο螅覀兿纫獔?zhí)行SVNManager對象的checkInObject方法,通過SVNRepository 執(zhí)行的ISVNEditor對象來在Subversion倉庫中的建立和更新域?qū)ο蟮陌姹荆挥性赾loseEdit被調(diào)用后,才會提交所有的操作。SVNDeltaGenerator類用于獲取當前版本與被更新版本之間的差異,Subversion通過存儲版本間差異部分的形式存放新的版本,這樣會使提高網(wǎng)絡效率。

          public SVNResult checkInObject(
          ????????????????BaseTrackingObject obj){
          ????????.....
          ????????//Obtain the editor handle from the
          ????????//repository
          ????????ISVNEditor editor = theRepository.
          ????????????????getCommitEditor(obj.
          ????????????????getModificationReason(), null);
          ????????....
          ????????//create the file at the specified path
          ????????????????editor.addFile(path, null, -1);
          ????????}
          ????????else {
          ????????????????//file is already present, so open
          ????????????????//the file in the repository
          ????????????????editor.openFile(path, -1);
          ????????}
          ????????....
          ????????String checksum = deltaGenerator.
          ????????????????????????sendDelta(path,
          ????????????????????????new ByteArrayInputStream(
          ????????????????????????obj.getXmlRepresentation().
          ????????????????????????getBytes()),
          ????????????????????????editor, true);
          ????????.....
          ????????editor.closeEdit();
          ????????...
          }



          檢索變化歷史

          ??? 為檢索指定領域?qū)ο蟮臍v史版本,需要調(diào)用SVNManager類的getRevisionLog方法; SVNRepository類的getLatestRevision方法可以得到當前版本號;SVNManager.log方法可以檢索每個版本的日志,日志可以包含版本修訂的日期、修改人、修改的內(nèi)容等信息;SVNManager.getFile方法可以從Subversion倉庫中取得領域?qū)ο笾付ò姹镜乃袃?nèi)容。

          public List getRevisionLog(BaseTrackingObject
          ????????obj, long startRevision,
          ????????long endRevision) {
          ????????.....
          ????????if(endRevision==-1) {
          ????????????????//obtain the latest revision from
          ????????????????//the repository
          ????????????????endRevision =
          ????????????????????????theRepository.getLatestRevision();
          ????????}
          ????????//retrieve the various log entries for
          ????????//the particular object path
          ????????Collection revisionLogs = theRepository.
          ????????????????log(new String[] {path}, null,
          ????????????????????????startRevision, endRevision,
          ????????????????????????false, true);
          ????????....
          ????????//Obtain the contents of the object at
          ????????//the specified revision
          ????????theRepository.getFile(path, revisionInfo.
          ????????????????getRevisionNumber(),
          ????????????????new Properties(),
          ????????????????xmlFileContentsStream);
          ????????....
          }

          檢索版本間的差異

          ??? SVNManager.showDifferences方法用來檢測兩個版本之間的差異,是通過調(diào)用JavaSVN 的SVNDiffManager類來去的差異,也可以通過SVNClientManager來引用并執(zhí)行這個類,SVNDiffManager的doDiff方法有一個默認的實現(xiàn),可以通過參數(shù)指定輸出流參數(shù)的形式取得固定格式的差異結(jié)果,我們也可以使用ISVNEditor來實現(xiàn)一個自己的差異比較方法。在這個例子里,我們使用默認的實現(xiàn)。

          public String showDifferences(
          ????????????????BaseTrackingObject obj,long revision1,
          ????????????????long revision2) {
          ????????....
          ????????//Create an instance of SVNClientManager
          ????????//providing authentication
          ????????SVNClientManager ourClientManager =
          ????????????????????????SVNClientManager.newInstance(
          ????????????????????????options, "name", "password");
          ????????//Obtain the handle to DiffClient
          ????????//from the client manager
          ????????SVNDiffClient theDiff = ourClientManager
          ????????????????????????.getDiffClient();
          ????????....
          ????????theDiff.doDiff(svnUrl, SVNRevision.
          ????????????????create(revision1), svnUrl,
          ????????????????SVNRevision.create(revision2),
          ????????????????false, false, diffStream);
          ????????....
          }



          結(jié)論

          ??? 在企業(yè)級應用里,不但要完成數(shù)據(jù)的存儲和檢索,還要實現(xiàn)對數(shù)據(jù)變化歷史的跟蹤。傳統(tǒng)方法是使用關(guān)系數(shù)據(jù)庫來完成這個工作,但是這不是一個“優(yōu)雅”的方案。在我們的貸款數(shù)據(jù)處理的例子里,Subversion提供了跟蹤數(shù)據(jù)變化的支持。JavaSVN的API用來完成數(shù)據(jù)存儲、檢索、獲取版本間差異和日志等任務。
          我們的例子只是一個簡單的性能演示,Subversion提供了豐富的功能支持,完全可以應用于企業(yè)級應用。祝你探索地更開心!

          資源
          +本文的范例代碼和相關(guān)的安裝介紹
          +Matrix Java社區(qū):http://www.matrix.org.cn
          +在www.chq.name也可以得到部分相關(guān)資源和信息

          關(guān)于作者
          Swaminathan Radhakrishnan works as a senior technical architect for Infosys Technologies, Ltd.
          Swaminathan Radhakrishnan 本文作者,Infosys技術(shù)有限公司的資深技術(shù)架構(gòu)師

          陳海青(joson),本文譯者,生活在中國的山東省煙臺市,先后從事軟件開發(fā)、數(shù)據(jù)庫管理、系統(tǒng)管理等工作,2001年獲得高級程序員資格。

          posted on 2007-02-15 08:30 好學蜘蛛 閱讀(228) 評論(0)  編輯  收藏 所屬分類: 版本控制


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 周至县| 中阳县| 黄山市| 旺苍县| 南郑县| 德兴市| 突泉县| 绵阳市| 澜沧| 岫岩| 娄底市| 贡觉县| 丹东市| 鹤壁市| 自贡市| 广灵县| 页游| 大连市| 鹤岗市| 海阳市| 明水县| 阳新县| 句容市| 苍山县| 宁波市| 曲麻莱县| 腾冲县| 张家界市| 乐昌市| 大余县| 中阳县| 沐川县| 兴化市| 改则县| 社会| 渝北区| 繁峙县| 长泰县| 广安市| 新宾| 基隆市|