??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
回首q去Q?.0版本是非常易用的Q其重要之处在于实现了透明ȀzM及其他重要特性,例如处理Runtime/Unchecked异常、MTOC(multi-transactional object-container 多事务对象容?客户端和服务器端的实C及在zd客户端的推更?pushed updates)。我们曾l的db4oCQ注册用户已l超q?5,000Q这一切告诉我们品的易用性是不容|疑的,其是原生对象的复杂映射完全可以与创可脓?band-aid)的ORM技术相抗衡?br />
展望未来Q?.0ȝ本的发布更加x性能Q当然还是保持一如既往的易用性。本着挑战性能极限和易用性的_Qdb4oq行了新一轮的改进Q涉及到了内部非常根基的部分。尽无法直观的看到改进了什么,但在q行的时候你能明昄体会到。db4o 8.0?a >标识理pȝq行了根本性的改变Q重Ҏ改进了db4o server的I/OҎ。正如Poleposition基准试所昄的,q些改进都应验了db4o的卓性能。未来,q些改进都ؓ改进I/O集群、碎片整理和对象演进做好了准备?br />
认识到db4o在嵌入式讑֤和桌面应用程序中的力量,我们扩展了db4o与大?a >Versant对象数据?/a>集成Q进行端到端对象持久化的能力Q而db4o复制技术可用于提供强大的从db4o高性能桌面到Versant大规模集服务器的纯对象持久化。与此同Ӟdb4o核心团队l把重点攑֜增强易用性,q在日益壮大的社Z扮演重要角色。例如增Z透明持久以及Ȁz?NET集合、安全特性、客户和服务器优化、适时的支持了Android和Silverlight之类的轻量环境?br />
在技术创新的同时QVersantl箋向开源社区敞开大门Q一直向C传播q这L声音Q对象数据库在互联网计算的新U元中是非常重要的。l保?.0的新业务模式和品预览发布策略,新的8.0遵@了更加流行的FLOSS开源授权模式,q持l提交和db4o一L开源管理工P例如OME(Object Manager Enterprise)工具以及Eclipse和Visual Studio插g?br />
注意Q这ơ新版本发布q是遵@标准程。下面是一个汇总,db4o团队在整?010q都会ؓ8.0的最l发布而努力:
新性能Ҏ?br />
内部Idpȝ改善I/O、集、碎片整理等 *
改进内存理——通过2的因?factor of 2)减小堆空?br />
在不同的负蝲Q有多种新的~存选项
快速集合的实现(BigSet)
自定义类型处理器
为client/server模式优化的对象预获取
新功?br />
从db4o到大哥Versant的对象复?*
针对Java?NET集合的TP/TA *
对Silverlight和Mono的支?br />
提供.NET LINQ支持
国际化——UnicodeQ现在还是UTF-8和其他字W串~码...支持中文、日文字W集
由开源社区提供的新功?br />
扩展开源授权——微?Ms-PL, Ms-RL)QFLOSS授权Q兼容GPL_v3
开源Eclipse和Visual Studio的OME插g
DZone RefCard以及新的技术视频和播客
像MapMeq样的Android应用E序demo
Eclipse和Visual Studio的TA/TP插g
新的易用性改q?br />
安全的套接字通讯
引进Maven资源库快?br />
ADO .NET Data Services接口(IQueryable, IUpdateable)
新的q行时统计收集和可视化分?br />
mdRS——ؓGoogle Android用户提供的移动dRSQ以便能复制到关pd数据?br />
Spring db4o扩展
对ؓI类型的Array的支?br />
化后的新配置界面
支持.NET枚D作ؓ值类?br />
业界率先支持CompactFramework上的LINQ
.NET普通集合类型的支持
为推更新客户端缓存准备的提交回调函数
?NET LINQ提供TP
集合感知的dRS实现
*h注的是RC版中不可用的Q但计划放进最l版?br />
Versant目标是ؓdb4oC用户提供最先进、最易用Q最坚固、遵循ACID且高性能的数据库解决Ҏ。新db4o 8.0的发布兑C我们始终奉行的承诺。我们期待听C的声韛_ƈ愿和你一起ƈ肩作战ؓ未来交付新的创新?br />
请帮助我们向你们的朋友和同事分nq样的声韻I“工作中用正的工具Q用对象数据库去应对互联|时代的数据理挑战?#8221;?br />
Robert Greene
开源运营V.P.
Versant——db4o团队
h意!引用、{贴本文应注明原译者:Rosen
Jiang 以及出处Q?/font>http://m.tkk7.com/rosen
]]>
ICOODB 2008
是本世纪对象数据库方面的W一ơ国际大?/b>Q将?/span>
3
?/span>
13
?/span>
14
日在德国柏林召开。对U学家、工业、开发者和学生来说Q在q里能面寚w交流象数据库q相互碰撞灵感,q是一ơ难得的Z。大会旨在让Z对对象数据库产生兴趣Q以一U?b style="mso-bidi-font-weight: normal">创新的方式把对象和数据库l合hQƈ代替或扩展关pd数据?/b>
/
映射
?/span>
大会׃个独立的委员会组l,来自柏林应用U技大学Q?/span>
TFH-Berlin
Q的
Stefan Edlich
教授和英国喀里多g大学Q?/span>
Glasgow Caledonian University
Q的
James Paterson
是本ơ大会的领导人,?/span>
ODBMS.org
?/span>
ODBMS
供应商、主要出版h提供支持Qƈ由柏林应用科技大学提供场所。大会将在柏林应用科技大学召开。在星期?/b>Q也是在?b style="mso-bidi-font-weight: normal">理论?/b>”,焦点在对象数据库的理论斚w?b style="mso-bidi-font-weight: normal">星期?/b>Q也是?b style="mso-bidi-font-weight: normal">应用?/b>”,焦点在实际应用和实现方面。ؓ技术日准备的每论文都进?b style="mso-bidi-font-weight: normal">审阅。更多关键信息、演讲和大会日程h?/span>
日程面
Q?/span>
|
|
对象数据库在某些特定的应用程序类型中是明智的选择Q这栯减少开发者成本和旉Q也能帮助他们构建更加富?/span> OO Ҏ的应用E序。否则,如果盲目地加大数据库I间Q迟早也q是会被关系数据库和 O/R 映射l充填满了。因此,本次大会的一个目的就是让大家能更好的理解什么情况下和ؓ什么?/span> ODBMS 。有了这U精,我们想邀请你加入本次 大会、v草一份论文或演讲、展Cv?/strong> 或简单的到场观摩或和我们q一步接z。如果你Ҏ个主题有兴趣Q只需要访?/span> odbms.org q?/span> 专家文章 或浏览包括演讲稿、指南、文章等在内?/span> 免费内容 ?/span>
|
?/font>
?/font>
?/font>
?/font>
?/font>
大会内容
感兴的主题被包括在内Q但不局限于此:
l
对象数据?b style="mso-bidi-font-weight: normal">研究
l
对象数据库与关系型技术、映?/span>
JPA
{的比较?/span>
l
对象数据库在工业、案例研IӞ能源、生物、移动领域、汽?/span>
?/span>
Q?/span>
l
对象数据?b style="mso-bidi-font-weight: normal">产品
l
对象数据库与性能
l
对象数据库与查询语言
l
对象数据?b style="mso-bidi-font-weight: normal">体系和模?/b>
l
对象数据库在嵌入式系l?/b>?/span>
l
对象数据库在高可用?/b>?b style="mso-bidi-font-weight: normal">可变规模pȝ?/span>
l
对象数据库的不同~程语言
l
对象数据库和标准Q例?/span>
odmg
?/span>
4th generation
”)
l
对象数据库的培训
l
对象数据?b style="mso-bidi-font-weight: normal">实现
如果你能在以上的M主题有所贡献Q或M其他相关主题Q请与我联系?/span>
最后,请参考本|站?/span>
FAQ
Q相xd
q里
查阅Q官Ҏv报可以在
q里
览?/span>
h意!引用、{贴本文应注明原译者:RosenJiang 以及出处Q?/font>
http://m.tkk7.com/rosen
屏幕截图
想看应用E序是如何运作的Q你可以观看?a >YouTube上的MapMe视频、从一个外部服务器下蝲高分辨率视频(30 Mb)或下面的屏幕截图Q?br />
db4o总部Q卫?交通视图)
MapMe主菜单:
建立书签/D?navpoint)Q?br />
保存的书{?D?navpoint)列表Q?br />
MapMe是如何运用db4o?/font>
如果你查看源代码Q下面有下蝲Q,你会发现DB helpercd理了所有的持久化操作(开启、存储、查询、计数数据库Q,而这一切都不超q?0行代码!
q一切都很简单,而且不会丧失性能。让我们来看一些项目中用到的持久化Ҏ?/p>
开启数据库
开启数据库的确单,q且在必要的时候还能自动生成数据库文g。一旦打开Qdb4o锁定数据库文g?/p>
注意QؓMapBookmark对象建立的烦引字D|“name”,q设|激zd更新U别?br />
保存书签
在这里我们调用一pd的操作,无论对象是否存在于数据库Q对象都会被更新或插入?/p>
在保存到数据库之前,我们讄好所有字Dc?/p>
Ҏ名字查询书签
我们通过Query by Example(QBE)传入一个原型来取回以名字ؓ条g的书{?/p>
QBE利用反射来检查原型对象的字段?br />
查询所有书{?/font>
q里我们把SODA查询l果拯到ArrayList中。但要注意,当用Native Queries时你不必q样做(在这U情况下直接返回List<MapBookmark>Q?/p>
删除书签
如果你的对象在db4o参考系l中存在Q你可以L的调用delete()操作从数据库中删除它?br />
书签计数
要通过查询来进行对象计敎ͼ你只要询问查询结果的大小卛_?br />
待完?/font>
下蝲
MapMe.Zip
YouTube上的MapMe视频
高分辨率视频(30 Mb)
h意!引用、{贴本文应注明原译者:RosenJiang 以及出处Q?/font>http://m.tkk7.com/rosen
在开源面向对象数据库 db4o 之旅 pd文章的第 1 部分Q?a >初识 db4o 中,作者介l了 db4o 的历史和现状Q应用领域,以及?ORM {的比较Q?在第 2 部分Q?a >db4o 查询方式? 作者介l了 db4o 的三U不同的查询方式QQBE、SODA 以及 Native QueriesQƈ分别通过q三U不同的途径实现了两个关联对象的查询?/p>
前面我们已经介绍了如何在 db4o 中查询以及添加对象,在本文中我们会向您介绍?db4o 中如何对对象q行更新以及删除操作?br />
场景一
我们来设惌L场景Q一位名叫“张三”的Z了RQƈ上好了牌照(如本pdW二部分之代码)Q而他基本信息的地址q不详细Q只写了“成都市”,在一ơ主部门检查此Z息的时候,发现了这个问题,q立即着手修攏V?/p>
?db4o 中,我们q样来实现对q个用户信息的修改(清单1Q:
package com; import bo.People; import com.db4o.Db4o; import com.db4o.ObjectContainer; import com.db4o.ObjectSet; import com.db4o.query.Predicate; public class DB4OTest{ public static void main(String[] args){ //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ ObjectSet<People> result = db.query(new Predicate<People>() { public boolean match(People people) { return people.getName().equals("张三"); } }); People people = result.next(); //修改地址 people.setAddress("成都市金牛区xxx?); db.set(people); }finally{ //关闭q接 db.close(); } } } |
修改数据是如此的单,通过 NQ 查询?People 对象Q接着修改其地址Q最后保存即可。现在我们来看看修改是否成功, 打开 ObjectManager Q如?1 所C,我们可以看到数据库里的用h据已l更C?/p>
与本pd文章W二部分不同的是Q我们利?ObjectSet<People> result 来获取返回结果,而不?List<People> list。查?ObjectSet ?API 我们发现 ObjectSet 实际上承了 java.util.List ?java.util.Iterator。ؓ什么要l承两个接口Q这是由?db4o Z方便开发者而有意这栯计的Qdb4o 的设计目标就是轻量Q这Ll承方式?ObjectSet 提供了多U特性,而无需开发者在多个集合接口之间转换?/p>
场景?/b>
让我们考虑下面q个场景:
׃工作原因Q“张三”要d省会d他城市发展,他的汽R也要在那里用,Z方便Q他q是军_重新更换为本地牌照?
q次我们几乎和场景一采用同样的代码,但结果却不同Q?a >清单2Q:
package com; import bo.People; import com.db4o.Db4o; import com.db4o.ObjectContainer; import com.db4o.ObjectSet; import com.db4o.query.Predicate; public class DB4OTest{ public static void main(String[] args){ //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ ObjectSet<People> result = db.query(new Predicate<People>() { public boolean match(People people) { return people.getName().equals("张三"); } }); People people = result.next(); //修改地址 people.setAddress("l阳市xx区xxx?); //修改车牌? people.getAutoInfoList().get(0).setLicensePlate("川B00000"); db.set(people); }finally{ //关闭q接 db.close(); } } } |
惛_应该保存成功了吧Q只是多加入了设|R牌的代码。打开 ObjectManagerQ如?2 所C。很奇怪,地址保存成功了,而R牌却Ҏ没变化?/p>
其实q也?db4o 的有意安排。设想一个复杂对象有很多成员Qƈ且这些成员又有自q成员。当更新该对象,db4o 不得不更新其所有的兌对象、关联对象的兌对象Q等{。这引起严重的性能惩罚Q而且在大部分的情况下是没有必要这L?/p>
db4o 引入了“更新深?update depth)”这一概念来控制被更新的对象成员树深度。默认的更新深度?1Q这意味着只有基本cd?String cd的成员变量可以被更新Q而修改对象成员将得不CQ何反映,例如本例中修?People 对象?_autoInfoList 成员?/p>
Z能更新成员对象,ob4o 提供?cascadeOnUpdate() ҎQ该Ҏ必须在每ơ开启数据库之前讄清单3Q?/p>
package com; import bo.People; import com.db4o.Db4o; import com.db4o.ObjectContainer; import com.db4o.ObjectSet; import com.db4o.query.Predicate; public class DB4OTest{ public static void main(String[] args){ //U联讄 Db4o.configure().objectClass("bo.People") .cascadeOnUpdate(true); //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ ObjectSet<People> result = db.query(new Predicate<People>() { public boolean match(People people) { return people.getName().equals("张三"); } }); People people = result.next(); //修改地址 people.setAddress("l阳市xx区xxx?); //修改车牌? people.getAutoInfoList().get(0).setLicensePlate("川B00000"); db.set(people); }finally{ //关闭q接 db.close(); } } } |
q下l于如愿以偿Q如?3 所C。其?db4o 为开发者想得很周到Q关键是如何用好q些Ҏ?/p>
场景?/b>
“张三”换了工作后Q事业发展很快,准备把R卖了换新的,于是他去交管部门办理UM手箋Q删除关联的车辆信息清单4Q?/p>
package com; import bo.AutoInfo; import com.db4o.Db4o; import com.db4o.ObjectContainer; import com.db4o.ObjectSet; import com.db4o.query.Predicate; public class DB4OTest{ public static void main(String[] args){ //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ ObjectSet<AutoInfo> result = db.query(new Predicate<AutoInfo>() { public boolean match(AutoInfo ai) { //匚w姓名和R牌号 return ai.getLicensePlate().equals("川B00000") && ai.getOwnerNo().getName().equals("张三"); } }); AutoInfo ai = result.next(); //删除车辆信息 db.delete(ai); }finally{ //关闭q接 db.close(); } } } |
?a >?4 所C,所兌的R辆信息已被删除了?/p>
场景?/b>
在场景三的基上修改一下,设想“张三”由于工作不,D最后维护汽车的开支都困难Q他不得不退出有车一族的行列清单5Q?/p>
package com; import bo.People; import com.db4o.Db4o; import com.db4o.ObjectContainer; import com.db4o.ObjectSet; import com.db4o.query.Predicate; public class DB4OTest{ public static void main(String[] args){ //U联讄 Db4o.configure().objectClass("bo.People") .cascadeOnDelete(true); //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ ObjectSet<People> result = db.query(new Predicate<People>() { public boolean match(People people) { //匚w姓名 return people.getName().equals("张三"); } }); People people = result.next(); //删除车主以及兌的R辆信? db.delete(people); }finally{ //关闭q接 db.close(); } } } |
用过 Hibernate 的开发者都知道Q它的联删除让人留下了深刻印象Q第一ơ用的时候都会ؓ之振奋。db4o 也ؓ开发者提供了U联删除Q和场景二的U联更新一P cascadeOnDelete() 是专门ؓ删除准备的,基本概念?cascadeOnUpdate() 一致。打开 ObjectManager 我们会发现数据库已经清空了,张三的购车经历到此结束?br />
通过本系列文章,db4o 的优势已l体现得淋漓致Q它的添加、更新、删除是如此的简单,正如 db4o 的口号那样——“仅需一行代码就能存储复杂结构对象,极大的降低了开发时间和成本Q提供高效的性能Q无需 DBA q预”?/p>
如本文有不详之处,大家可以参考官方的《用h南》或讉K db4o 官方中文论坛Qdb4o 中文C正在火热成长Q?br />
学习
获得产品和技?/b>
讨论
|
![]() |
Rosen Jiang 来自成都Q是 db4o ?OO 的忠?fansQ是 2005 q?db4o ?dvp 获得者之一。他正在 J2me 应用中?db4oQ你可以通过 rosener_722@hotmail.com 和他联系?/p> |
![]() |
||
|
![]() |
Chris 来自香港Q热爱开源和 db4o。他创办了中国最火热?Java 和开源社?MatrixQhttp://www.Matrix.org.cnQ, 你可以通过 chris@Matrix.org.cn 和他联系?/p> |
![]() |
||
|
![]() |
张黄瞩,热爱开源YӞ熟悉 Java/C/C++ ~程语言Q对数据库技术网l技术均感兴。你可以通过 zhanghuangzhu@gmail.com 联系他?/p> |
?开源面向对象数据库 db4o 之旅 pd文章的第一部分Q?a >初识 db4o 中,作者介l了 db4o 的历史和现状Q应用领域,以及?ORM {的比较。在q篇文章中,作者将会介l?db4o 的安装、启动以及三U不同的查询方式QQBEQQuery by ExampleQ、SODAQSimple Object Database AccessQ?以及 NQQNative QueriesQ,q分别通过q三U不同的途径实现了两个关联对象的查询。本文还C了开发中最l常用到的几个典型功能的 db4o 实现?/p>
db4o 所有最新的版本都可以直接在官方|站上下载,q入 db4o ?a target="_blank">下蝲面Q我们可以看到最新的 for Java E_版本?5.5Q包?JAR、源代码、入门文档、API {内容的完整的打包文件只?6 MBQdb4o q有一个对象数据库理工具 ObjectManagerQ目前版本是 1.8Q请在参考资源中下蝲Q?/p>
接着?Eclipse 中新?Java 目Q把 db4o 对象数据库引擎包 db4o-5.5-java5.jar 导入q项目。由?db4o 支持多种版本?JDKQ除?for JDK 5.0 ?db4o-5.5-java5.jar 外,q有 for JDK 1.1?.2-1.4 ?JAR 包,以适应多种环境。与 Hibernate、iBATIS SQL Maps 相比Qdb4o 更加自然Q无需q多地引用第三方支持库?/p>
db4o 怎样q行对象持久化呢Q通过览目录可以发现Q与传统?RDBMS 一Pdb4o 也有自己的数据库文g, ?db4o 中数据库文g的后~名是?.yap”。让我们先来了解一?db4o 对象数据库引擎的主要包结构:
db4o 提供两种q行模式Q分别是本地模式和服务器模式。本地模式是指直接在E序里打开 db4o 数据库文件进行操作:
ObjectContainer db = Db4o.openFile("auto.yap"); |
而服务器模式则是客户端通过 IP 地址、端口以及授权口令来讉K服务器:
服务器端Q?ObjectServer server=Db4o.openServer("auto.yap",1212); server.grantAccess("admin","123456"); |
ObjectContainer db=Db4o.openClient("192.168.0.10",1212,"admin","123456"); |
两种方式都可以得?ObjectContainer 实例Q就目前 Java EE 应用环境来看Q服务器模式更有现实意义Q而本地模式更适合于嵌入式应用。ؓ了简化演C,本文在下面的例子都将采用本地模式?/p>
在下面的例子里,我们都会用到下面两个对象Q?People ?AutoInfo 对象?/p>
People 对象Q?/p>
清单1. People 对象
package bo; public class People { private java.lang.Integer _id; private java.lang.String _name; private java.lang.String _address; private java.util.List<AutoInfo> _autoInfoList; public java.lang.Integer getId() { return _id; } public void setId(java.lang.Integer _id) { this._id = _id; } public java.lang.String getName() { return _name; } public void setName(java.lang.String _name) { this._name = _name; } public java.lang.String getAddress() { return _address; } public void setAddress(java.lang.String _address) { this._address = _address; } public java.util.List<AutoInfo> getAutoInfoList() { return this._autoInfoList; } public void addAutoInfo(AutoInfo _autoInfoList) { if (null == this._autoInfoList) this._autoInfoList = new java.util.ArrayList<AutoInfo>(); this._autoInfoList.add(_autoInfoList); } } |
AutoInfo 对象Q?/p>
清单2. AutoInfo 对象
package bo; public class AutoInfo{ private java.lang.Integer _id; private java.lang.String _licensePlate; private bo.People _ownerNo; public java.lang.Integer getId () { return _id; } public void setId (java.lang.Integer _id) { this._id = _id; } public java.lang.String getLicensePlate () { return _licensePlate; } public void setLicensePlate (java.lang.String _licensePlate) { this._licensePlate = _licensePlate; } public bo.People getOwnerNo () { return this._ownerNo; } public void setOwnerNo (bo.People _ownerNo) { this._ownerNo = _ownerNo; } } |
利用 set Ҏ把新对象存入 ObjectContainerQ而对 ObjectContainer 中已有对象进?set 操作则是更新该对象。db4o 保存数据库很单,下面是一个段完整的保存对象的代码Q?/p>
AutoInfo 对象Q?/p>
清单3
package com; import bo.AutoInfo; import bo.People; import com.db4o.Db4o; import com.db4o.ObjectContainer; public class DB4OTest{ public static void main(String[] args){ //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ //构?People 对象 People peo = new People(); peo.setId(1); peo.setAddress("成都?); peo.setName("张三"); //构?AutoInfo 对象 AutoInfo ai = new AutoInfo(); ai.setId(1); ai.setLicensePlate("川A00000"); //讄 People ?AutoInfo 的关p? ai.setOwnerNo(peo); peo.addAutoInfo(ai); //保存对象 db.set(peo); }finally{ //关闭q接 db.close(); } } } |
当我们运行上qC码,db4o 会自动创建“auto.yap”文件。让我们来看看到底保存成功没有,打开 ObjectManager 工具Q?font color="#996699">?1 所C?/p>
?. 对象数据库管理工?/b>
“File”->“Open File”->选择刚才我们保存的“auto.yap”文Ӟ“auto.yap”文件可在项目的根目录下扑ֈQ,最新的 ObjectManager 1.8 版本为我们提供了“Read Only”方式读取数据库文gQ避?ObjectManager 占用数据库文件所D的程序异常?/p>
打开之后Q图 2 所C,刚才存贮?People 对象已经在数据库中了Qƈ且还可以很直观的看到 AutoInfo 对象也放入了 ArrayList 中。这U可视化的对象关pL利于我们Ҏ据的理解Q是传统 RDBMS 无法比拟的。有些开发者会?ObjectManager 工具略显单,q点我想随着 db4o 的不断发展会加入更多的特性。在q个工具中,我们意外的发C Java 集合对象的踪影,db4o 把与 ArrayList 有直接关pȝ所有接口和父类都保存了Q这h得更直观?/p>
在此Q我保留?_id 属性,q是因ؓ通常?Java EE 环境中,DAO W一ơ不是把整个对象都返回到表现层,而是只返回了“标题”、“发布时间”这些信息(q式的q回idQ,接着 DAO 与数据库断开Q要查看详情Q比如文章内容)需要进?findById 操作Q这?DAO 要再ơ与数据库交互,只有唯一标识W才能正地扑ֈ对象。这U?i>懒加?/i>方式也是很多书籍所推荐的?/p>
回到本文的范例程序中Q这?_id 属性可׃h工编码实现的“序列”进行赋|当然 db4o 也提供了内部标识W?Internal IDsQ图 2 中的 id=1669Q以?UUIDs?/p>
?. 对象l构
?RDBMS 一Pdb4o 也有自己的查询语aQ分别是 QBEQQuery by ExampleQ、NQQNative QueriesQ、SODAQSimple Object Database AccessQ,db4o 更推荐?NQ q行查询。NQ 方式提供了非常强大的查询功能Q支持原生语aQ也意味着你可以?Java 来判断该对象是否W合条gQ这是其他数据库查询语言无法比拟的。在某些情况下, db4o 核心会将 NQ 译?SODA 以获得更高的性能。下面详l介l一下这三种查询语言?/p>
QBE 规范可在q里下蝲。QBE 最初由 IBM 提出Q同时业界也有许多和 QBE 兼容的接口,包括著名?Paradox。有些系l,比如微Y?AccessQ它的基于表单的查询也是受到了部?QBE 思想的启发。在 db4o 中,用户可借用 QBE 快速上手,可以很容易适应 db4o 存取数据的方式?/p>
当利?QBE ?db4o 提供模板QexampleQ对象时Qdb4o 返回所有和非默认值字D匹配的全部对象。内部是通过反射所有的字段和构造查询表辑ּQ所有非默认值字D늻合”AND”表辑ּQ来实现?/p>
例如Q利?QBE 查找到R牌号为“川A00000”的车主姓名Q这是一个联查询?/p>
清单4
package com; import java.util.List; import bo.AutoInfo; import com.db4o.Db4o; import com.db4o.ObjectContainer; public class DB4OTest{ public static void main(String[] args){ //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ //构造模板对? AutoInfo ai = new AutoInfo(); ai.setLicensePlate("川A00000"); //查询对象 List<AutoInfo> list = db.get(ai); for(int x = 0; x < list.size(); x++){ System.out.println("车主姓名Q?+list.get(x).getOwnerNo().getName()); } }finally{ //关闭q接 db.close(); } } } |
但是 QBE 也有明显的限Ӟdb4o 必须反射模板QexampleQ对象的所有成员;无法执行更进一步的查询表达式(例如 AND、OR、NOT {等Q;不能U束 0Q整型)、””(I字W串Q或?nullQ对象)Q因些都被认为是不受U束的。要l过q些限制Qdb4o 提供?NQQNative QueriesQ?/p>
SODAQSimple Object Database AccessQ?/font>
SODA Q简单对象数据库讉KQ请查看官方站点Q其中一位主要维护者是 Carl RosenbergerQCarl 正是 db4o 首席架构师?/p>
SODA 是一U与数据库通讯的对?API。最l的目标是实现类型安全、对象复用、最的字符串用、与~程语言无关{特性。SODA ?db4o 最底层的查?APIQ目?SODA 中用字W串来定义字D,q样不能实现类型安全也无法在编译时查代码,而且写v来较ȝQ当然要辑ֈ设计目标q个阶段是必ȝ。大部分情况?NQQNative QueriesQ是很好的查询接口,不过遇到动态生成查询的时?SODA 大有作Z?/p>
通过 SODA 查找到R牌号为“川A00000”的车主姓名Q?/p>
清单5
package com; import java.util.List; import bo.AutoInfo; import com.db4o.Db4o; import com.db4o.ObjectContainer; import com.db4o.query.Query; public class DB4OTest{ public static void main(String[] args){ //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ //构造查询对? Query query=db.query(); //讄被约束实? query.constrain(AutoInfo.class); //讄被约束实例的字段和约束条? query.descend("_licensePlate").constrain("川A00000"); //查询对象 List<AutoInfo> list = query.execute(); for(int x = 0; x < list.size(); x++){ System.out.println("车主姓名Q?+list.get(x).getOwnerNo().getName()); } }finally{ //关闭q接 db.close(); } } } |
通过 APIQ发?Query 实例增加?sortBy 按字D|序方法和 orderAscending正序、orderDescending 倒序排列ҎQSODA ?QBE 更进了一步?/p>
_ֽL在最后出场,NQ 才是 db4o 查询方式中最_ֽ的地方!有没有想q用你熟悉的的编E语aq行数据库查询呢Q要是这P你的查询代码是 100% 的类型安全?00% 的编译时查以?100% 的可重构Q很奇妙吧?NQ 可以做到q些?/p>
有两论文专门讲解了 NQ 的基本概念和设计思\Q分别是 《Cook/RosenbergerQ持久对象原生数据库查询语言?/font> ?《Cook/RaiQSafe Query Objects: Statically Typed Objects as Remotely Executable Queries》。作为结果集的一部分QNQ 表达式必返?true 值来标记特定实例。如果可能的?db4o 尝试优?NQ 表达式,q依赖烦引来q行表达式?/p>
通过 NQ 查找到R牌号为“川A00000”的车主姓名Q?/p>
清单6
package com; import java.util.List; import bo.AutoInfo; import com.db4o.Db4o; import com.db4o.ObjectContainer; import com.db4o.query.Predicate; public class DB4OTest{ public static void main(String[] args){ //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ List <AutoInfo> list = db.query(new Predicate<AutoInfo>() { public boolean match(AutoInfo ai) { //q样才是cd安全? return ai.getLicensePlate().equals("川A00000"); } }); for(int x = 0; x < list.size(); x++){ System.out.println(list.get(x).getOwnerNo().getName()); } }finally{ //关闭q接 db.close(); } } } |
必须指出 NQ 的一个的问题是:在内部,db4o 设法?NQ 转换?SODA。但q不是所有的查询表达式都可以成功转换。有些查询表辑ּ的流向图QflowgraphQ非帔R于分析。这U情况下Qdb4o 不得不实例化一些持久对象来真实地运?NQ 表达式?/p>
正在开发中?NQ 查询优化器就可以化解q个障碍Q它分?NQ 表达式的每个部分Q以保最量的实例化对象Q以此提高性能。当Ӟ优化器的不是灵丹妙药Q关键还需要自己多优化代码?/p>
开?Java EE 目l常会用到分,怎样?NQ 实现呢?向数据库写入六条记录Q?/p>
清单7
package com; import java.util.List; import bo.AutoInfo; import com.db4o.Db4o; import com.db4o.ObjectContainer; import com.db4o.query.Predicate; public class DB4OTest{ public static void main(String[] args){ //打开数据? ObjectContainer db = Db4o.openFile("auto.yap"); try{ List<AutoInfo> list = db.query(new Predicate<AutoInfo>() { public boolean match(AutoInfo ai) { return true; } }); //记录L Integer count = list.size(); //每页两条Q分三页 for(int x = 0; x < 3; x++){ System.out.println("W?+x+":"+list.get(x*2).getLicensePlate()); System.out.println("W?+x+":"+list.get(x*2+1).getLicensePlate()); } }finally{ //关闭q接 db.close(); } } } |
我们发现Q在q行 NQ 查询时ƈ没有加入M条gQ无条gq回 trueQ,是不是相当于遍历了整个数据库Qdb4o 的设计者早想Cq个问题Q当 db.query() 执行完毕q回 list 实例的时候,db4o 只是与数据库同步取出内部 IDs 而已Qƈ没有把所有的 AutoInfo 对象全部取出Q只有在 list.get(x*2).getLicensePlate() 之后才会L?IDs 取出记录。所以不必担心性能问题?/p>
db4o 为开发者提供了多种查询方式Q这些方式都很灵zR要引v大家注意的是Q灵zd带来便利的同时也对开发者自w素质提Z更高的要求,Q比如排序,既可以用 SODA 也可以用 Java 集合对象实现Q在开发过E中一定要形成某种l一的开发模式,q样 db4o 才能最高效能地为我所用?/p>
作者简?/p>
Rosen Jiang 来自成都Q是 db4o ?OO 的忠?fansQ是 2005 q?db4o ?dvp 获得者之一。他正在 J2me 应用中?db4oQ你可以通过 rosener_722@hotmail.com 和他联系?
Chris 来自香港Q热爱开源和 db4o。他创办了中国最火热?Java 和开源社?MatrixQ?a >http://www.Matrix.org.cnQ, 你可以通过 chris@Matrix.org.cn 和他联系?br />
张黄瞩,热爱开源YӞ熟悉 Java/C/C++ ~程语言Q对数据库技术网l技术均感兴。你可以通过 zhanghuangzhu@gmail.com 联系他?br />
IBM DeveloperWorks(IBM DW) 版权所有!引用、{贴本文应注明本文来自 IBM DW?/font>