




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、面向?qū)ο髷?shù)據(jù)庫 db4o 之旅第 1 部分: 初識 db4oRosen Jiang, 軟件工程師, db4o 和 OO 的忠實 fansRosen Jiang 來自成都,是 db4o 和 OO 的忠實 fans,是 2005 年 db4o 的 dvp 獲得者之一。他正在 J2me 應(yīng)用中使用 db4o,你可以通過 rosener_722 和他聯(lián)系。張 黃矚 (zhanghuangzhugmailcom), 軟件工程師, 熱愛開源軟件張黃矚,熱愛開源軟件,熟悉 Java/C/C+ 編程語言,對數(shù)據(jù)庫技術(shù)網(wǎng)絡(luò)技術(shù)均感興趣。你可以通過 zhanghuangzhu 聯(lián)系他。Chris (chrisMa
2、trixorgcn), Matrix 創(chuàng)辦者, MatrixChris 來自香港,熱愛開源和 db4o。他創(chuàng)辦了中國最火熱的 Java 和開源社區(qū) Matrix(http:/www.M), 你可以通過 chrisM 和他聯(lián)系。簡介: 本文為 db4o 之旅 系列文章的第一篇,介紹了面向?qū)ο髷?shù)據(jù)庫 db4o 的基本特性,并且與傳統(tǒng)關(guān)系型數(shù)據(jù)庫以及 OR 映射技術(shù)做了比較分析,讀者可以體驗到 db4o 的全新的面向?qū)ο蟠鎯Φ睦砟?,并且給出了性能測試數(shù)據(jù)。前言業(yè)界對持久存儲領(lǐng)域的追求從未停止過,為了更方便、更容易地用對象表達我們的思維,開源領(lǐng)域和商業(yè)領(lǐng)域都涌現(xiàn)了許多新技術(shù), ORM 的出現(xiàn)
3、恰恰說明了這點。最近一年,業(yè)界也在反思,到底 ORM 給我們帶來的是便利還是麻煩。矛頭指向大名鼎鼎的 Hibernate ,紛紛議論其性能問題,大家似乎要達成這樣的共識:“在業(yè)務(wù)邏輯復(fù)雜的地方用 SP ,而一般的 CRUD 還是 Hibernate ”,就連全球知名的 BearingPoint 也有類似看法。下面一個簡單的例子,說明了傳統(tǒng) ORM 工具的弊端。讓我們考慮一個簡單的 Student 對象如清單1:清單1 Student 類public class Student private String name; private int age; public String getName
4、() return name; public int getAge() return age; 考慮下面這個場景:找到“年齡小于 20 歲的所有學(xué)生”?使用 ORL 實現(xiàn)如清單2:清單2 ORL 實現(xiàn)String oql = "select * from student in AllStudents where studentage <20" OQLQuery query = new OQLQuery(oql); Object students = queryexecute(); 使用 JDOQL 實現(xiàn)如清單3:清單3 JDOQL 實現(xiàn)Query query = pe
5、rsistenceManagernewQuery(Studentclass, "age <20"); Collection students = (Collection)queryexecute(); 上面的方法都存在一些普遍問題: · 現(xiàn)代集成開發(fā)環(huán)境不會檢查內(nèi)嵌字符串的語義和語法錯誤。在上面所有查詢語句中, age 字段和數(shù)值 20 都被認(rèn)為是數(shù)字類型,但是沒有一個 IDE 或編譯器能檢查其實際正確性。如果開發(fā)者混淆了查詢代碼比如,改變了 age 字段的名字或類型,將導(dǎo)致上面所有的查詢語句在運行時報錯,而不會在編譯時提示。 · 現(xiàn)代敏捷開發(fā)技術(shù)
6、鼓勵不斷進行重構(gòu)來維持清晰和與時俱進的類模型,以便準(zhǔn)確重現(xiàn)不斷演進的域模型。如果查詢代碼難于維護,它會延遲決定重構(gòu)的時間并不可避免的引入低質(zhì)量代碼。 · 所有列出的查詢都直接用 Student 類的私有成員 age,而不是使用它的公共接口 studentgetAge(),因此他們都破壞了面向?qū)ο蠓庋b規(guī)則,違反接口和實現(xiàn)應(yīng)該分離的面向?qū)ο蠓▌t。 · 所有的查詢都非 100% 的原生。 既然存在如此多的問題, 為什么不直接使用純面向?qū)ο髷?shù)據(jù)庫呢?有些開發(fā)者可能會說:“它缺乏數(shù)學(xué)模型的支持, 還不夠成熟”。的確, RDBMS 發(fā)展了幾十年才有今天的成就,已經(jīng)非常完善了。而技術(shù)的革
7、新是無止境的, 故步自封的永遠(yuǎn)都跟不上變化的腳步。 讓我們來簡單回顧一下對象數(shù)據(jù)庫的發(fā)展史(資料來源于 Wiki 百科全書):“面向?qū)ο髷?shù)據(jù)庫系統(tǒng)”這一術(shù)語第一次出現(xiàn)于 1985 年。著名的研究項目包括:Encore-Ob/Server ( 布朗大學(xué)), EXODUS(Wisconsin 大學(xué)), IRIS (惠普), ODE ( Bell 實驗室), ORION (MCC ) ,Vodak (GMD-IPSI)和 Zeitgeist (Texas Instruments)。其中以 ORION 項目發(fā)表的論文數(shù)為最多。 MCC 的 Won Kim 將這些論文中最有價值的一部分匯編成書并由 MI
8、T 出版社出版。對象數(shù)據(jù)庫管理系統(tǒng)為面向?qū)ο缶幊陶Z言增加了持久的概念。最早的商品化 ODBMS 出現(xiàn)在 1986 年,是 Servio 公司(現(xiàn)在的 GemStone 公司)和 Ontos 公司推出的。后來(九十年代) Object Design ( ODI )、 Versant 、 Objectivity 、 O2 Technology 、 Poet 、 Ibex 、 UniSQL 和 ADB MATISSE 等公司也加入了這個開拓行列。而今天,一家來自加州硅谷的開源面向?qū)ο髷?shù)據(jù)庫公司 db4objects 為我們帶來了db4o, 一款性能卓越的純面向?qū)ο髷?shù)據(jù)庫,也是我們這篇和后續(xù)文章將會介
9、紹的主角。db4o 為我們帶來的是這樣一種面向?qū)ο蟮牟樵兎绞?· 100% 的原生 查詢語言應(yīng)能用實現(xiàn)語言( Java 或 C# )完全表達,并完全遵循實現(xiàn)語言的語義。 · 100% 的面向?qū)ο?查詢語言應(yīng)可運行在自己的實現(xiàn)語言中,允許未經(jīng)優(yōu)化執(zhí)行普通集合而不用自定義預(yù)處理。 · 100% 的類型安全 查詢語言應(yīng)能完全獲取現(xiàn)代 IDE 的特性,比如語法檢測、類型檢測、重構(gòu),等等。 什么是 db4o“利用表格存儲對象,就像是將汽車開回家,然后拆成零件放進車庫里,早晨可以再把汽車裝配起來。但是人們不禁要問,這是不是泊車的最有效的方法呢?!?Esther Dyson d
10、b4o 是一個開源的純面向?qū)ο髷?shù)據(jù)庫引擎,對于 Java 與 NET 開發(fā)者來說都是一個簡單易用的對象持久化工具,使用簡單。同時,db4o 已經(jīng)被第三方驗證為具有優(yōu)秀性能的面向?qū)ο髷?shù)據(jù)庫, 下面的基準(zhǔn)測試圖對 db4o 和一些傳統(tǒng)的持久方案進行了比較。db4o 在這次比較中排名第二,僅僅落后于JDBC。通過圖 1 的基準(zhǔn)測試結(jié)果,值得我們細(xì)細(xì)品味的是采用 Hibernate/HSQLDB 的方案和 JDBC/HSQLDB 的方案在性能方面有著顯著差距,這也證實了業(yè)界對 Hibernate 的擔(dān)憂。而 db4o 的優(yōu)異性能,讓我們相信: 更 OO 并不一定會犧牲性能。圖1 HSQLDB 基準(zhǔn)測試
11、同時,db4o 的一個特點就是無需 DBA 的管理,占用資源很小,這很適合嵌入式應(yīng)用以及 Cache 應(yīng)用, 所以自從 db4o 發(fā)布以來,迅速吸引了大批用戶將 db4o 用于各種各樣的嵌入式系統(tǒng),包括流動軟件、醫(yī)療設(shè)備和實時控制系統(tǒng)。db4o 由來自加州硅谷的開源數(shù)據(jù)庫公司 db4objects 開發(fā)并負(fù)責(zé)商業(yè)運營和支持。db4o 是基于 GPL 協(xié)議。db4objects 于 2004 年在 CEO Christof Wittig 的領(lǐng)導(dǎo)下組成,資金背景包括 Mark Leslie 、 Veritas 軟件公司 CEO 、 Vinod Khosla ( Sun 公司創(chuàng)始人之一)、 Sun
12、公司 CEO 在內(nèi)的硅谷高層投資人組成。毫無疑問,今天 db4objects 公司是硅谷炙手可熱的技術(shù)創(chuàng)新者之一。db4o 特性db4o 的目標(biāo)是提供一個功能強大的,適合嵌入的數(shù)據(jù)庫引擎,可以工作在設(shè)備,移動產(chǎn)品,桌面以及服務(wù)器等各種平臺。主要特性如下:· 開源模式。與其他 ODBMS 不同,db4o 為開源軟件,通過開源社區(qū)的力量驅(qū)動開發(fā) db4o 產(chǎn)品。 · 原生數(shù)據(jù)庫。db4o 是 100% 原生的面向?qū)ο髷?shù)據(jù)庫,直接使用編程語言來操作數(shù)據(jù)庫。程序員無需進行 OR 映射來存儲對象,大大節(jié)省了程序員在存儲數(shù)據(jù)的開發(fā)時間。 · 高性能。圖2為 db4o 官方公布
13、的基準(zhǔn)測試數(shù)據(jù),db4o 比采用 Hibernate/MySQL 方案在某些測試線路上速度高出 44 倍之多!并且安裝簡單,僅僅需要 400Kb 左右的 jar 或 dll 庫文件。在接下來的系列文章中,我們將只關(guān)注在 Java 平臺的應(yīng)用,但是實際上 db4o 毫無疑問會很好地在 NET 平臺工作。 圖2 db4o 官方基準(zhǔn)測試數(shù)據(jù)· 易嵌入。使用 db4o 僅需引入 400 多 k 的 jar 文件或是 dll 文件,內(nèi)存消耗極小。 · 零管理。使用 db4o 無需 DBA,實現(xiàn)零管理。 · 支持多種平臺。db4o 支持從 Java 11 到 Java 50,
14、此外還支持 NET 、 CompactFramework 、 Mono 等 NET 平臺,也可以運行在 CDC 、 PersonalProfile 、 Symbian 、 Savaje 以及 Zaurus 這種支持反射的 J2ME 方言環(huán)境中,還可以運行在 CLDC 、 MIDP 、 RIM/Blackberry 、 Palm OS 這種不支持反射的 J2ME 環(huán)境中。 或許開發(fā)者會問,如果現(xiàn)有的應(yīng)用環(huán)境已經(jīng)有了關(guān)系型數(shù)據(jù)庫怎么辦?沒關(guān)系,db4o 的 dRS(db4o Replication System)可實現(xiàn) db4o 與關(guān)系型數(shù)據(jù)庫的雙向同步(復(fù)制),如圖 3 。 dRS 是基于 Hi
15、bernate 開發(fā),目前的版本是 10 ,并運行在 Java 12 或更高版本平臺上,基于 dRS 可實現(xiàn) db4o 到 Hibernate/RDBMS 、 db4o 到 db4o 以及 Hibernate/RDBMS 到 Hibernate/RDBMS 的雙向復(fù)制。dRS 模型如圖3圖3 dRS 模型結(jié)論db4o 因為其開源的理念,以及創(chuàng)新的實現(xiàn),獲得了 Java Pro 2006 讀者選擇獎。無論從成功案例還是 db4o 本身來看,這款純面向?qū)ο髷?shù)據(jù)庫都值得我們關(guān)注,從官方論壇反饋情況看,有相當(dāng)?shù)挠脩魷?zhǔn)備把關(guān)系型數(shù)據(jù)庫遷移到 db4o 。而最新發(fā)布的 55 版本,更是把性能再次提升很多。
16、在接下來的文章中,我會繼續(xù)和大家分享 db4o 給我們帶來的這場面向?qū)ο髷?shù)據(jù)庫風(fēng)暴。第 2 部分: db4o 查詢方式Rosen Jiang, 軟件工程師, db4o 和 OO 的忠實 fansRosen Jiang 來自成都,是 db4o 和 OO 的忠實 fans,是 2005 年 db4o 的 dvp 獲得者之一。他正在 J2me 應(yīng)用中使用 db4o,你可以通過 rosener_722 和他聯(lián)系。Chris (chrisMatrixorgcn), Matrix 創(chuàng)辦者, MatrixChris 來自香港,熱愛開源和 db4o。他創(chuàng)辦了中國最火熱的 Java 和開源社區(qū) Matrix(h
17、ttp:/www.M), 你可以通過 chrisM 和他聯(lián)系。張 黃矚 (zhanghuangzhugmailcom), 軟件工程師, 熱愛開源軟件張黃矚,熱愛開源軟件,熟悉 Java/C/C+ 編程語言,對數(shù)據(jù)庫技術(shù)網(wǎng)絡(luò)技術(shù)均感興趣。你可以通過 zhanghuangzhu 聯(lián)系他。簡介: 這篇文章是 db4o 之旅 系列文章的第二篇,介紹了面向?qū)ο髷?shù)據(jù)庫 db4o 的安裝、啟動以及三種查詢語言,并對三種查詢語言做了比較。查看本系列更多內(nèi)容標(biāo)記本文!前言在 db4o 之旅 系列文章的第一部分:初識 db4o 中,作者介紹了 db4o 的歷史和現(xiàn)狀,應(yīng)用領(lǐng)域,以及和 ORM 等的比較。
18、在這篇文章中,作者將會介紹 db4o 的安裝、啟動以及三種不同的查詢方式:QBE(Query by Example)、SODA(Simple Object Database Access) 以及 NQ(Native Queries),并分別通過這三種不同的途徑實現(xiàn)了兩個關(guān)聯(lián)對象的查詢。本文還示范了開發(fā)中最經(jīng)常用到的幾個典型功能的 db4o 實現(xiàn)。下載和安裝 db4odb4o 所有最新的版本都可以直接在官方網(wǎng)站上下載,進入 db4o 的下載頁面,我們可以看到最新的 for Java 穩(wěn)定版本是 55,包括 JAR、源代碼、入門文檔、API 等內(nèi)容的完整的打包文件只有 6 MB,db4o 還有一個
19、對象數(shù)據(jù)庫管理工具 ObjectManager,目前版本是 18(請在參考資源中下載)。接著在 Eclipse 中新建 Java 項目,把 db4o 對象數(shù)據(jù)庫引擎包 db4o-55-java5jar 導(dǎo)入進項目。由于 db4o 支持多種版本的 JDK,除了 for JDK 50 的 db4o-55-java5jar 外,還有 for JDK 11、12-14 的 JAR 包,以適應(yīng)多種環(huán)境。與 Hibernate、iBATIS SQL Maps 相比,db4o 更加自然,無需過多地引用第三方支持庫。開啟數(shù)據(jù)庫db4o 怎樣進行對象持久化呢?通過瀏覽目錄可以發(fā)現(xiàn),與傳統(tǒng)的 RDBMS 一樣,d
20、b4o 也有自己的數(shù)據(jù)庫文件, 在 db4o 中數(shù)據(jù)庫文件的后綴名是“*yap”。讓我們先來了解一下 db4o 對象數(shù)據(jù)庫引擎的主要包結(jié)構(gòu):· comdb4o comdb4o 包含了使用 db4o 時最經(jīng)常用到的功能。兩個最重要的接口是 comdb4oDb4o 和 comdb4oObjectCdb4oDb4o 工廠是運行 db4o 的起點,這個類中的靜態(tài)方法可以開啟數(shù)據(jù)庫文件、啟動服務(wù)器或連接一個已經(jīng)存在的服務(wù)器,還可以在開啟數(shù)據(jù)庫之前進行 db4o 環(huán)境配置。comdb4oObjectContainer 接口很重要,開發(fā)過程中 99% 的時間都會用到它,Ob
21、jectContainer 可在單用戶模式下作為數(shù)據(jù)庫實例,也可作為 db4o 服務(wù)器的客戶端。每個 ObjectContainer 實例都有自己的事務(wù)。所有的操作都有事務(wù)保證。當(dāng)打開 ObjectContainer,就已經(jīng)進入事務(wù)了,commit() 或 rollback() 時,下一個事務(wù)立即啟動。每個 ObjectContainer 實例維護它自己所管理的已存儲和已實例化對象,在需要 ObjectContainer 的時候,它會一直保持開啟狀態(tài),一旦關(guān)閉,內(nèi)存中數(shù)據(jù)庫所引用的對象將被丟棄。 · comdb4oext 你也許想知道為什么在 ObjectContainer 中只能看
22、見很少的方法,原因如下:db4o 接口提供了兩個途徑,分別在 comdb4o 和 comdb4oext 包中。這樣做首先是為了讓開發(fā)者能快速上手;其次為了讓其他產(chǎn)品能更容易的復(fù)制基本的 db4o 接口;開發(fā)者從這一點上也能看出 db4o 是相當(dāng)輕量級的。每個 comdb4oObjectContainer 對象也是 comdb4oextExtObjectContainer 對象。可以轉(zhuǎn)換成 ExtObjectContainer 獲得更多高級特性。 · comdb4oconfig comdb4oconfig 包含了所有配置 db4o 所需的類。 · comdb4oquery c
23、omdb4oquery 包包含了構(gòu)造“原生查詢, NQ(Native Queries)”所需的 Predicate 類。NQ 是 db4o 最主要的查詢接口。 db4o 提供兩種運行模式,分別是本地模式和服務(wù)器模式。本地模式是指直接在程序里打開 db4o 數(shù)據(jù)庫文件進行操作:ObjectContainer db = Db4oopenFile("autoyap");而服務(wù)器模式則是客戶端通過 IP 地址、端口以及授權(quán)口令來訪問服務(wù)器:服務(wù)器端: ObjectServer server=Db4oopenServer("autoyap",1212);serve
24、rgrantAccess("admin","123456");客戶端: ObjectContainer db=Db4oopenClient("192168010",1212,"admin","123456");兩種方式都可以得到 ObjectContainer 實例,就目前 Java EE 應(yīng)用環(huán)境來看,服務(wù)器模式更有現(xiàn)實意義;而本地模式更適合于嵌入式應(yīng)用。為了簡化演示,本文在下面的例子都將采用本地模式。在下面的例子里,我們都會用到下面兩個對象: People 和 AutoInfo 對象。Peo
25、ple 對象清單1:清單1 People 對象package bo;public class People private javalangInteger _id;private javalangString _name;private javalangString _address;private javautilList<AutoInfo> _autoInfoList;public javalangInteger getId() return _id;public void setId(javalangInteger _id) this_id = _id;public java
26、langString getName() return _name;public void setName(javalangString _name) this_name = _name;public javalangString getAddress() return _address;public void setAddress(javalangString _address) this_address = _address;public javautilList<AutoInfo> getAutoInfoList() return this_autoInfoList;publ
27、ic void addAutoInfo(AutoInfo _autoInfoList) if (null = this_autoInfoList)this_autoInfoList = new javautilArrayList<AutoInfo>();this_autoInfoListadd(_autoInfoList);AutoInfo 對象清單2:清單2 AutoInfo 對象package bo;public class AutoInfoprivate javalangInteger _id;private javalangString _licensePlate;priv
28、ate boPeople _ownerNo;public javalangInteger getId () return _id;public void setId (javalangInteger _id) this_id = _id;public javalangString getLicensePlate () return _licensePlate;public void setLicensePlate (javalangString _licensePlate) this_licensePlate = _licensePlate;public boPeople getOwnerNo
29、 () return this_ownerNo;public void setOwnerNo (boPeople _ownerNo) this_ownerNo = _ownerNo;利用 set 方法把新對象存入 ObjectContainer,而對 ObjectContainer 中已有對象進行 set 操作則是更新該對象。db4o 保存數(shù)據(jù)庫很簡單,下面就是一個段完整的保存對象的代碼:AutoInfo 對象清單3:清單3package com;import boAutoInfo;import boPeople;import comdb4oDb4o;import comdb4oObjectC
30、ontainer;public class DB4OTestpublic static void main(String args)/打開數(shù)據(jù)庫ObjectContainer db = Db4oopenFile("autoyap");try/構(gòu)造 People 對象People peo = new People(); peosetId(1);peosetAddress("成都市");peosetName("張三");/構(gòu)造 AutoInfo 對象AutoInfo ai = new AutoInfo();aisetId(1);aiset
31、LicensePlate("川A00000");/設(shè)置 People 和 AutoInfo 的關(guān)系aisetOwnerNo(peo);peoaddAutoInfo(ai);/保存對象dbset(peo);finally/關(guān)閉連接dbclose();當(dāng)我們運行上述代碼,db4o 會自動創(chuàng)建“autoyap”文件。讓我們來看看到底保存成功沒有,打開 ObjectManager 工具,如圖 1 所示。圖1 對象數(shù)據(jù)庫管理工具“File”>“Open File”>選擇剛才我們保存的“autoyap”文件(“autoyap”文件可在項目的根目錄下找到),最新的 Objec
32、tManager 18 版本為我們提供了“Read Only”方式讀取數(shù)據(jù)庫文件,避免 ObjectManager 占用數(shù)據(jù)庫文件所導(dǎo)致的程序異常。打開之后,如圖 2 所示,剛才存貯的 People 對象已經(jīng)在數(shù)據(jù)庫中了,并且還可以很直觀的看到 AutoInfo 對象也放入了 ArrayList 中。這種可視化的對象關(guān)系有利于我們對數(shù)據(jù)的理解,是傳統(tǒng) RDBMS 無法比擬的。有些開發(fā)者會說 ObjectManager 工具略顯簡單,這點我想隨著 db4o 的不斷發(fā)展會加入更多的特性。在這個工具中,我們意外的發(fā)現(xiàn)了 Java 集合對象的蹤影,db4o 把與 ArrayList 有直接關(guān)系的所有接
33、口和父類都保存了,這樣顯得更直觀。在此,我保留了 _id 屬性,這是因為通常在 Java EE 環(huán)境中,DAO 第一次不是把整個對象都返回到表現(xiàn)層,而是只返回了“標(biāo)題”、“發(fā)布時間”這些信息(并隱式的返回id),接著 DAO 與數(shù)據(jù)庫斷開;要查看詳情(比如文章內(nèi)容)就需要進行 findById 操作,這時 DAO 要再次與數(shù)據(jù)庫交互,只有唯一標(biāo)識符才能正確地找到對象。這種懶加載方式也是很多書籍所推薦的。回到本文的范例程序中,這個 _id 屬性可由人工編碼實現(xiàn)的“序列”進行賦值,當(dāng)然 db4o 也提供了內(nèi)部標(biāo)識符 Internal IDs,如圖 2 中的 id=1669;以及 UUIDs。圖2
34、對象結(jié)構(gòu)查詢數(shù)據(jù)庫和 RDBMS 一樣,db4o 也有自己的查詢語言,分別是 QBE(Query by Example)、NQ(Native Queries)、SODA(Simple Object Database Access),db4o 更推薦使用 NQ 進行查詢。NQ 方式提供了非常強大的查詢功能,支持原生語言,也就意味著你可以使用 Java 來判斷該對象是否符合條件,這是其他數(shù)據(jù)庫查詢語言無法比擬的。在某些情況下, db4o 核心會將 NQ 翻譯成 SODA 以獲得更高的性能。下面詳細(xì)介紹一下這三種查詢語言。QBE(Query by Example)QBE 規(guī)范可在這里下載。QBE 最
35、初由 IBM 提出,同時業(yè)界也有許多和 QBE 兼容的接口,包括著名的 Paradox。有些系統(tǒng),比如微軟的 Access,它的基于表單的查詢也是受到了部分 QBE 思想的啟發(fā)。在 db4o 中,用戶可借用 QBE 快速上手,可以很容易適應(yīng) db4o 存取數(shù)據(jù)的方式。當(dāng)利用 QBE 為 db4o 提供模板(example)對象時,db4o 將返回所有和非默認(rèn)值字段匹配的全部對象。內(nèi)部是通過反射所有的字段和構(gòu)造查詢表達式(所有非默認(rèn)值字段結(jié)合”AND”表達式)來實現(xiàn)。例如,利用 QBE 查找到車牌號為“川A00000”的車主姓名,這是一個級聯(lián)查詢。清單4:清單4package com;impor
36、t javautilList;import boAutoInfo;import comdb4oDb4o;import comdb4oObjectContainer;public class DB4OTestpublic static void main(String args)/打開數(shù)據(jù)庫ObjectContainer db = Db4oopenFile("autoyap");try/構(gòu)造模板對象AutoInfo ai = new AutoInfo();aisetLicensePlate("川A00000");/查詢對象List<AutoInfo&
37、gt; list = dbget(ai); for(int x = 0; x < listsize(); x+) Systemoutprintln("車主姓名:"+listget(x)getOwnerNo()getName();finally/關(guān)閉連接dbclose();但是 QBE 也有明顯的限制:db4o 必須反射模板(example)對象的所有成員;無法執(zhí)行更進一步的查詢表達式(例如 AND、OR、NOT 等等);不能約束 0(整型)、”(空字符串)或者 null(對象),因為這些都被認(rèn)為是不受約束的。要繞過這些限制,db4o 提供了 NQ(Native Que
38、ries)。SODA(Simple Object Database Access)SODA ,簡單對象數(shù)據(jù)庫訪問,請查看官方站點,其中一位主要維護者是 Carl Rosenberger,Carl 正是 db4o 首席架構(gòu)師。SODA 就是一種與數(shù)據(jù)庫通訊的對象 API。最終的目標(biāo)是實現(xiàn)類型安全、對象復(fù)用、最小的字符串使用、與編程語言無關(guān)等特性。SODA 是 db4o 最底層的查詢 API,目前 SODA 中使用字符串來定義字段,這樣將不能實現(xiàn)類型安全也無法在編譯時檢查代碼,而且寫起來較麻煩,當(dāng)然要達到設(shè)計目標(biāo)這個階段是必須的。大部分情況下 NQ(Native Queries)是很好的查詢接口,
39、不過遇到動態(tài)生成查詢的時候 SODA 就大有作為了。通過 SODA 查找到車牌號為“川A00000”的車主姓名。清單5:清單5package com;import javautilList;import boAutoInfo;import comdb4oDb4o;import comdb4oObjectContainer;import comdb4oqueryQuery;public class DB4OTestpublic static void main(String args)/打開數(shù)據(jù)庫ObjectContainer db = Db4oopenFile("autoyap&qu
40、ot;);try/構(gòu)造查詢對象Query query=dbquery();/設(shè)置被約束實例queryconstrain(AutoInfoclass);/設(shè)置被約束實例的字段和約束條件querydescend("_licensePlate")constrain("川A00000");/查詢對象List<AutoInfo> list = queryexecute(); for(int x = 0; x < listsize(); x+) Systemoutprintln("車主姓名:"+listget(x)getOwne
41、rNo()getName();finally/關(guān)閉連接dbclose();通過 API,發(fā)現(xiàn) Query 實例增加了 sortBy 按字段排序方法和 orderAscending正序、orderDescending 倒序排列方法,SODA 比 QBE 更進了一步。NQ(Native Queries)精彩總是在最后出場,NQ 才是 db4o 查詢方式中最精彩的地方!有沒有想過用你熟悉的的編程語言進行數(shù)據(jù)庫查詢呢?要是這樣,你的查詢代碼將是 100% 的類型安全、100% 的編譯時檢查以及 100% 的可重構(gòu),很奇妙吧?NQ 可以做到這些。有兩篇論文專門講解了 NQ 的基本概念和設(shè)計思路,分別是
42、Cook/Rosenberger,持久對象原生數(shù)據(jù)庫查詢語言 和 Cook/Rai,Safe Query Objects: Statically Typed Objects as Remotely Executable Queries。作為結(jié)果集的一部分,NQ 表達式必須返回 true 值來標(biāo)記特定實例。如果可能的話 db4o 將嘗試優(yōu)化 NQ 表達式,并依賴索引來運行表達式。通過 NQ 查找到車牌號為“川A00000”的車主姓名。清單6:清單6package com;import javautilList;import boAutoInfo;import comdb4oDb4o;import
43、 comdb4oObjectContainer;import comdb4oqueryPredicate;public class DB4OTestpublic static void main(String args)/打開數(shù)據(jù)庫ObjectContainer db = Db4oopenFile("autoyap");tryList <AutoInfo> list = dbquery(new Predicate<AutoInfo>() public boolean match(AutoInfo ai) /這樣才是類型安全的 return aiget
44、LicensePlate()equals("川A00000"); ); for(int x = 0; x < listsize(); x+) Systemoutprintln(listget(x)getOwnerNo()getName();finally/關(guān)閉連接dbclose();必須指出 NQ 的一個的問題是:在內(nèi)部,db4o 設(shè)法把 NQ 轉(zhuǎn)換成 SODA。但并不是所有的查詢表達式都可以成功轉(zhuǎn)換。有些查詢表達式的流向圖(flowgraph)非常難于分析。這種情況下,db4o 將不得不實例化一些持久對象來真實地運行 NQ 表達式。正在開發(fā)中的 NQ 查詢優(yōu)化器就可
45、以化解這個障礙,它將分析 NQ 表達式的每個部分,以確保最少量的實例化對象,以此提高性能。當(dāng)然,優(yōu)化器的不是靈丹妙藥,關(guān)鍵還需要自己多優(yōu)化代碼。開發(fā) Java EE 項目經(jīng)常會用到分頁,怎樣用 NQ 實現(xiàn)呢?向數(shù)據(jù)庫寫入六條記錄。清單7:清單7package com;import javautilList;import boAutoInfo;import comdb4oDb4o;import comdb4oObjectContainer;import comdb4oqueryPredicate;public class DB4OTestpublic static void main(Strin
46、g args)/打開數(shù)據(jù)庫ObjectContainer db = Db4oopenFile("autoyap");tryList<AutoInfo> list = dbquery(new Predicate<AutoInfo>() public boolean match(AutoInfo ai) return true; );/記錄總數(shù)Integer count = listsize();/每頁兩條,分三頁 for(int x = 0; x < 3; x+) Systemoutprintln("第"+x+"頁:
47、"+listget(x*2)getLicensePlate(); Systemoutprintln("第"+x+"頁:"+listget(x*2+1)getLicensePlate();finally/關(guān)閉連接dbclose();我們發(fā)現(xiàn),在進行 NQ 查詢時并沒有加入任何條件(無條件返回 true),是不是相當(dāng)于遍歷了整個數(shù)據(jù)庫?db4o 的設(shè)計者早就想到了這個問題,當(dāng) dbquery() 執(zhí)行完畢返回 list 實例的時候,db4o 只是與數(shù)據(jù)庫同步取出內(nèi)部 IDs 而已,并沒有把所有的 AutoInfo 對象全部取出,只有在 listge
48、t(x*2)getLicensePlate() 之后才會去根據(jù) IDs 取出記錄。所以不必?fù)?dān)心性能問題。結(jié)論db4o 為開發(fā)者提供了多種查詢方式,這些方式都很靈活。要引起大家注意的是:靈活在帶來便利的同時也對開發(fā)者自身素質(zhì)提出了更高的要求,(比如排序,既可以用 SODA 也可以用 Java 集合對象實現(xiàn))在開發(fā)過程中一定要形成某種統(tǒng)一的開發(fā)模式,這樣 db4o 才能最高效能地為我所用。第 3 部分: 深入db4oRosen Jiang, 軟件工程師, db4o 和 OO 的忠實 fansRosen Jiang 來自成都,是 db4o 和 OO 的忠實 fans,是 2005 年 db4o 的
49、dvp 獲得者之一。他正在 J2me 應(yīng)用中使用 db4o,你可以通過 rosener_722 和他聯(lián)系。Chris (chrisMatrixorgcn), Matrix 創(chuàng)辦者, MatrixChris 來自香港,熱愛開源和 db4o。他創(chuàng)辦了中國最火熱的 Java 和開源社區(qū) Matrix(http:/www.M), 你可以通過 chrisM 和他聯(lián)系。張 黃矚 (zhanghuangzhugmailcom), 軟件工程師, 熱愛開源軟件張黃矚,熱愛開源軟件,熟悉 Java/C/C+ 編程語言,對數(shù)據(jù)庫技術(shù)網(wǎng)絡(luò)技術(shù)均感興趣。你可以通過 zhanghuangzhu 聯(lián)系他。簡介:
50、這篇文章是開源面向?qū)ο髷?shù)據(jù)庫 db4o 之旅 系列文章的第 3 部分,介紹面向?qū)ο髷?shù)據(jù)庫 db4o 的修改和刪除,并對其中出現(xiàn)的問題進行細(xì)致分析,引入了“更新深度(update depth)”這一重要概念。前言在開源面向?qū)ο髷?shù)據(jù)庫 db4o 之旅 系列文章的第 1 部分:初識 db4o 中,作者介紹了 db4o 的歷史和現(xiàn)狀,應(yīng)用領(lǐng)域,以及和 ORM 等的比較; 在第 2 部分:db4o 查詢方式中, 作者介紹了 db4o 的三種不同的查詢方式:QBE、SODA 以及 Native Queries,并分別通過這三種不同的途徑實現(xiàn)了兩個關(guān)聯(lián)對象的查詢。前面我們已經(jīng)介紹了如何在 db4o 中查詢以
51、及添加對象,在本文中我們將會向您介紹在 db4o 中如何對對象進行更新以及刪除操作。更新數(shù)據(jù)場景一我們來設(shè)想這樣的場景:一位名叫“張三”的人買了車,并上好了牌照(如本系列第二部分之代碼),而他基本信息的地址并不詳細(xì),只寫了“成都市”,在一次主管部門檢查此人信息的時候,發(fā)現(xiàn)了這個問題,并立即著手修改。在 db4o 中,我們這樣來實現(xiàn)對這個用戶信息的修改(清單1):清單1 修改地址package com;import boPeople;import comdb4oDb4o;import comdb4oObjectContainer;import comdb4oObjectSet;import co
52、mdb4oqueryPredicate;public class DB4OTestpublic static void main(String args)/打開數(shù)據(jù)庫ObjectContainer db = Db4oopenFile("autoyap");tryObjectSet<People> result = dbquery(new Predicate<People>() public boolean match(People people) return peoplegetName()equals("張三"); );Peop
53、le people = resultnext();/修改地址peoplesetAddress("成都市金牛區(qū)xxx號");dbset(people);finally/關(guān)閉連接dbclose();修改數(shù)據(jù)是如此的簡單,通過 NQ 查詢出 People 對象,接著修改其地址,最后保存即可?,F(xiàn)在我們來看看修改是否成功, 打開 ObjectManager ,如圖 1 所示,我們可以看到數(shù)據(jù)庫里的用戶數(shù)據(jù)已經(jīng)更新了。圖1 修改地址與本系列文章第二部分不同的是,我們利用 ObjectSet<People> result 來獲取返回結(jié)果,而不是 List<People&
54、gt; list。查閱 ObjectSet 的 API 我們發(fā)現(xiàn) ObjectSet 實際上繼承了 javautilList 和 javautilIterator。為什么要繼承兩個接口?這是由于 db4o 為了方便開發(fā)者而有意這樣設(shè)計的,db4o 的設(shè)計目標(biāo)就是輕量級,這樣的繼承方式為 ObjectSet 提供了多種特性,而無需開發(fā)者在多個集合接口之間轉(zhuǎn)換。場景二讓我們考慮下面這個場景:由于工作原因,“張三”要離開省會去其他城市發(fā)展,他的汽車也要在那里使用,為了方便,他還是決定重新更換為本地牌照。 這次我們幾乎和場景一采用同樣的代碼,但結(jié)果卻不同(清單2):清單2 修改地址和車牌(不成功)pa
55、ckage com;import boPeople;import comdb4oDb4o;import comdb4oObjectContainer;import comdb4oObjectSet;import comdb4oqueryPredicate;public class DB4OTestpublic static void main(String args)/打開數(shù)據(jù)庫ObjectContainer db = Db4oopenFile("autoyap");tryObjectSet<People> result = dbquery(new Predicate<People>() public boolean match(People people) return peoplegetName()equals("張三"); );People people = resultnext();/修改地址peo
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 延邊大學(xué)《城市設(shè)計Ⅰ》2023-2024學(xué)年第二學(xué)期期末試卷
- 四川省成都經(jīng)開區(qū)實驗高級中學(xué)2025屆高考模擬調(diào)研卷數(shù)學(xué)試題(一)含解析
- 江蘇省鹽城市東臺實驗中學(xué)2025年中考抽測語文試題樣題(A卷)試卷含解析
- 武夷學(xué)院《細(xì)胞生物學(xué)實驗》2023-2024學(xué)年第一學(xué)期期末試卷
- 遼寧省撫順市清原縣2025年數(shù)學(xué)三下期末統(tǒng)考試題含解析
- 上海市金山區(qū)金山中學(xué)2025屆高三期末試題含解析
- 江蘇省丹陽市2025年校初三4月考語文試題含解析
- 重慶第二師范學(xué)院《多媒體制作》2023-2024學(xué)年第一學(xué)期期末試卷
- 泰州學(xué)院《外科學(xué)各論》2023-2024學(xué)年第二學(xué)期期末試卷
- 閩南理工學(xué)院《隧道工程(B)》2023-2024學(xué)年第二學(xué)期期末試卷
- 2024年音樂節(jié)行業(yè)發(fā)展前景預(yù)測及投資策略研究報告
- 2024西部縣域經(jīng)濟百強研究
- 2025-2030年中國IPTV產(chǎn)業(yè)行業(yè)發(fā)展趨勢及前景調(diào)研分析報告
- 國企改革三年行動培訓(xùn)
- 醫(yī)美診所院感知識培訓(xùn)課件
- 河北省氣象部門招聘筆試沖刺題2025
- 上海市家庭居室裝飾裝修施工合同書
- 物聯(lián)網(wǎng)技術(shù)及應(yīng)用基礎(chǔ)(第2版) -電子教案
- 新能源汽車租賃市場發(fā)展方案
- 貨架回收合同范例
- (2024年)中國傳統(tǒng)文化介紹課件
評論
0/150
提交評論