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