db4o的查询
在不同的应用中,数据库的增删改查操作的频率是不一样的,但一般情况下使用的更多的是查询操作。查询的简易程度、速度是查询的两个重要参数。
db4o查询的优势
用过RDBMS的“程序猿”们都知道,对于其他数据库几乎所有的操作都是通过SQL语句来完成,这就造成一个非常大的弊端:那就是在没有出来结果之前,我们并不知道SQL语言是不是正确的(没有任何的语法检查),只有当程序运行后才能看出程序是否出错。在多数情况下这种错误的查找与修改是要耗费大量人力物力的。而db4o基本就不会出现这个问题。
db4o(.NET和jave两种版本)支持三种查询方法:示例查询(QBE),原生查询(NQ)和SODA API。当然还是那句话,.NET的用户比较有福气,因为.NET 版本还外加支持LINQ,LINQ是.NET的官方推荐查询方法。既然要讲查询,那就全部都讲一下。
QBE(Query by Example)
QBE 最初由 IBM 提出,同时业界也有许多和 QBE 兼容的接口,包括著名的 Paradox。有些系统,比如微软的 Access,它的基于表单的查询也是受到了部分 QBE 思想的启发。在 db4o 中,用户可借用 QBE 快速上手,可以很容易适应 db4o 存取数据的方式。
当利用 QBE 为 db4o 提供模板(example)对象时,db4o 将返回所有和非默认值字段匹配的全部对象。内部是通过反射所有的字段和构造查询表达式(所有非默认值字段结合”AND”表达式)来实现。
说的直白一点就是你先来一个对象,这个对象某些牲是固定的(比方你在班中查询年龄为14岁的女生,则Person这个类固定两个发生Age = 14,Sexual = female),这个对象就是一个示例(Example),然后把这个示例传递给数据库,就可以查询出所有符合条件的对象。
示例代码如下:
public class DB4OTest{
public static void main(String[] args){
//打开数据库
ObjectContainer db = Db4o.openFile("auto.yap");
try{
//构造模板对象
Person p1 = new Person();
p1.Age = 14;
p1.setSexual = famale;
//查询对象
List<Person> list = db.get(p1);
for(int x = 0; x < list.size(); x++){
output(p1.Name);
}
}finally{
//关闭连接
db.close();
}
}
}
不知道大家有没有发现一个问题,那就是如果,如果我们对int类型的Age来设定值,那会出现什么情况?所有的年龄的都能查出来??其实是不能的,因为int类型即使没有赋值,那他也有一个默认值为0,那么这个查询只能查到年龄为0的人。。。让人很无语。
这就是 QBE 的最明显的限制:不能约束 0(整型)、””(空字符串)或者 null(对象),因为这些都被认为是不受约束的。还有就是db4o 必须反射模板(example)对象的所有成员;无法执行更进一步的查询表达式(例如 AND、OR、NOT 等等)。要绕过这些限制,db4o 提供了 NQ(Native Queries)。
SODA(Simple Object Database Access)
大家先不用着急,最好的总是放在最后面,先讲一下SODA。SODA 就是一种与数据库通讯的对象 API。最终的目标是实现类型安全、对象复用、最小的字符串使用、与编程语言无关等特性。SODA 是 db4o 最底层的查询 API,目前 SODA 中使用字符串来定义字段,这样将不能实现类型安全也无法在编译时检查代码,而且写起来较麻烦,当然要达到设计目标这个阶段是必须的。大部分情况下 NQ(Native Queries)是很好的查询接口,不过遇到动态生成查询的时候 SODA 就大有作为了。
// retrievePilotByName
IQuery query = db.Query();
query.Constrain(typeof(Pilot));
query.Descend("_name").Constrain("Michael Schumacher");
IObjectSet result = query.Execute();
ListResult(result);
上面就是查询了一个名字叫Michael Schumacher的飞行员。通过 API,发现 Query 实例增加了 sortBy 按字段排序方法和 orderAscending正序、orderDescending 倒序排列方法,SODA 比 QBE 更进了一步。
NQ(Native Queries)
不得不说,NQ是一种非常优秀的查询方法,而且最为不容易的是,他是类型安全的,编译时可以检查语法,可重构,先给大家看一个示例:
// retrieveCarsByPilotNameNative
string pilotName = "Rubens Barrichello";
List<Car> results = db.Query<Car>(delegate(Car car) {
return car.Pilot.Name == pilotName; });
listResults(results);
大家看明白了吧?有点难懂?说明你的C#基础不是很好,这里面为了保证类型安全,使用了泛型,委托和匿名函数,而且用起来也是挺方便。啊,不知道怎么用?其实我也不是很明白,如果你是java用户,可以好好研究一下,给大家推荐一篇文章,
LINQ
最后就是大餐了,唉,请我怎么讲LINQ呢?先说说LINQ的好处吧,前面NQ的好处它都有,而且基本思想和NQ也比较类似,为了保证类型安全,做出了非常多的努力。但是微软(LINQ是微软的产品)的聪明之处在于他用了一种更加易读的语法,将里面高深的技术全部隐藏起来。所以LINQ的语法像自然语言一样自然。额。。。我讲的有点多了,好吧,最后一句:LINQ还是一个很大的工程的,来龙去脉用单田芳的方式来讲的话应该可以讲几个月吧,那基础知道我们就不来的,直接上语法。
// retrievePilot
IEnumerable<Pilot> result = from Pilot p in db
where p.Name.StartsWith("Michael")
select p;
ListResult(result);
有没有熟悉感扑面而来,有没有一下子就明白这些代码在做什么?对,这就是LINQ的魅力,也是db4o的魅力。LINQ的具体细节我给大家推荐一篇文章:http://www.cnblogs.com/liulun/ ... .html,怎么样,大家30分钟看完了吗?反正我是没有看完,但是看完之后真的对LINQ的原理的非常清楚。对看其他文章的帮助很大。
查询的四种方法就到这里吧,每一种只是一个入门。如果有必要我会对LINQ方法再做一个更为详细的教程,因为我觉得LINQ才是C#版的db4o的查询的精华所在。当然db4o的LINQ和其他方法用的LINQ的差别不大,所以大家也可以找其他的教程。