db4o学习笔记(四)、db4o查询详解续

摘要:

  在上一单元中对db4o中采用QBE及NQ对数据库进行查询作了详细的讨论,今天将就其提供的底层查询接口SODA进行介绍,内容包括(1)、SODA查询对象的创建;(2)、约束条件的使用及约束表达式;(3)、对于三种查询方式各自适合的应用场景进行了简要的介绍。

  正文:

  SODAdb4o提供的底层查询接口,允许开发人员直接操作查询表达式树中的节点,它采用字符串标识对象数据成员,但是这种方式既不是类型安全也不在编译时进行检查并且写起来十分冗长。

  对大多数应用程序来说使用NQ将是很好的选择。

  SODA也有其它两种查询不可比拟的优势,那就是使用你的应用程序能够动态生成查询,这也是部分应用开发所需的。

  3.3.1、简单查询

  让我们以上一单元中熟悉的QBE查询转换为SODA为例开始吧,通过ObjectContainer#.query()方法并为其提供约束条件实例来获取一个新的Query对象,在查询所有车手的示例中,对于查询的约束为Pilot类对象。

1
2
3
4
5
[retrieveAllPilots]
Query query = db.Query();
query.Constrain(typeof(Pilot));
ObjectSet result = query.Execute();
ListResult(result);

  基本上来说,我们只是使用描述对象的元数据来替换先前提供了实例原型来获取想要查询的资料,系统将会构建一个包含查询节点及约束的表达式树,查询节点用于容纳查询结果的候选对象,约束条件决定了哪些应用包含/排队在查询结果中。

  第一个简单的表达式树(图解)看上去会是这样的。

original.aspx

  我们向数据库中询问所有类型为Pilot的候选对象并将其聚集到我们的查询结果中。

  为了通过车手名字进行查询,我们需要扩展上述约束条使其包含待查询对象的”name”字段的相应字符串。

1
2
3
4
5
6
[retrievePilotByName]
Query query = db.Query();
query.Constrain(typeof(Pilot));
query.Descend("_name").Constrain("Michael Schumacher");
ObjectSet result = query.Execute();
ListResult(result);

  使用”descend”的目的是将附加的约束条件增加到表达式树(图解)中以判断我们的候选对象,就像上述原型实例一样。

original.aspx

  因此,满足这个查询的候选对象需要是Pilot类型并且其数据成员”name”必须与给出的字符串相匹配才能加入到结果集中。

  需要引起注意的是类约束并不是必需的,如果让其为空将会查询所有拥有”name”成员为给定值的对象,大多数情况下这似乎并不我们所希望的结果。

  通过车手积分进行精确的查询如下:

  

1
2
3
4
5
6
[retrievePilotByExactPoints]
Query query = db.Query();
query.Constrain(typeof(Pilot));
query.Descend("_points").Constrain(100);
ObjectSet result = query.Execute();
ListResult(result);

  3.3.2、高级查询

  现在我们并不希望通过对象成员的精确匹配来进行查询了,而是更希望通过值域或者不包含给定成员值的对象等,这些约束接口都提供了支持。

  首先,来看看查询不是”Michael Schumacher”的工作是如何完成的?

1
2
3
4
5
6
[retrieveByNegation]
Query query = db.Query();
query.Constrain(typeof(Pilot));
query.Descend("_name").Constrain("Michael Schumacher").Not();
ObjectSet result = query.Execute();
ListResult(result);

  如果查询表达式的结果为假将会阻止后续的布尔运算操作。

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[retrieveByConjunction]
Query query = db.Query();
query.Constrain(typeof(Pilot));
Constraint constr = query.Descend("_name")
.Constrain("Michael Schumacher");
query.Descend("_points")
.Constrain(99).And(constr);
ObjectSet result = query.Execute();
ListResult(result);
/// ---
[retrieveByDisjunction]
Query query = db.Query();
query.Constrain(typeof(Pilot));
Constraint constr = query.Descend("_name")
.Constrain("Michael Schumacher");
query.Descend("_points")
.Constrain(99).Or(constr);
ObjectSet result = query.Execute();
ListResult(result);

  也可以在查询中对给定值作比较运算。

1
2
3
4
5
6
7
[retrieveByComparison]
Query query = db.Query();
query.Constrain(typeof(Pilot));
query.Descend("_points")
.Constrain(99).Greater();
ObjectSet result = query.Execute();
ListResult(result);

  查询接口还允许对数据成员的默认进行查询及对查询结果进行排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[retrieveByDefaultFieldValue]
Pilot somebody = new Pilot("Somebody else", 0);
db.Set(somebody);
Query query = db.Query();
query.Constrain(typeof(Pilot));
query.Descend("_points").Constrain(0);
ObjectSet result = query.Execute();
ListResult(result);
db.Delete(somebody);
/// 以下是对查询结果进行排序
[retrieveSorted]
Query query = db.Query();
query.Constrain(typeof(Pilot));
query.Descend("_name").OrderAscending();
ObjectSet result = query.Execute();
ListResult(result);
query.Descend("_name").OrderDescending();
result = query.Execute();
ListResult(result);

  上述所有条件都可以进行任意的组合以完成更复杂的操作,当然还是会存在其难于完成的任务,不用担心db4o早就想到这一点啦Stick out tongue这可以通过db4o提供的求值运算(表达式)来完成,求值运算将会在后续的章节中进行讨论。

  3.3.3、小结

  现在对db4o数据库的查询工作我们可以通过其提供的三种方式中的任意一种来完成,它们分别是:(1)、QBE;(2)、NQ;(3)、SODA  对于何时采用哪种方式进行查询,我们的建议是:

  1)、NQ作为db4o主要的查询接口将是我们不二的首选;

  2)、当前版本中对NQ查询的优化操作总是以SODA方式来执行的,因此SODA可以作为系统优化的一种途径,同时它总是用来在运行时动态的生成查询。

  3)、QBE对于初学者来说将是很好的选择,当然它在功能上会有些限制,如果你喜欢的话有时对的应用还是很适合的Stick out tongue

  当然综合运用这几种方式会更好。

  在完成练习后我们知道了db4o所提供的几种查询方式,但是我们的领域模型并不复杂才仅公一个类而矣,在下一章中将对db4o中处理复合对象进行讨论。

ContractedBlock.gif ExpandedBlockStart.gif 完整代码
  1None.gifusing System;
  2None.gifusing com.db4o;
  3None.gifusing com.db4o.query;
  4None.gifusing com.db4o.f1;
  5None.gifnamespace com.db4o.f1.chapter1
  6ExpandedBlockStart.gifContractedBlock.gifdot.gif{
  7InBlock.gif    public class QueryExample : Util
  8ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
  9InBlock.gif        public static void Main(string[] args)
 10ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 11InBlock.gif            ObjectContainer db = Db4o.OpenFile(Util.YapFileName);
 12InBlock.gif            try
 13ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 14InBlock.gif                StoreFirstPilot(db);
 15InBlock.gif                StoreSecondPilot(db);
 16InBlock.gif                RetrieveAllPilots(db);
 17InBlock.gif                RetrievePilotByName(db);
 18InBlock.gif                RetrievePilotByExactPoints(db);
 19InBlock.gif                RetrieveByNegation(db);
 20InBlock.gif                RetrieveByConjunction(db);
 21InBlock.gif                RetrieveByDisjunction(db);
 22InBlock.gif                RetrieveByComparison(db);
 23InBlock.gif                RetrieveByDefaultFieldValue(db);
 24InBlock.gif                RetrieveSorted(db); 
 25InBlock.gif                ClearDatabase(db);
 26ExpandedSubBlockEnd.gif            }

 27InBlock.gif            finally
 28ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 29InBlock.gif                db.Close();
 30ExpandedSubBlockEnd.gif            }

 31ExpandedSubBlockEnd.gif        }

 32InBlock.gif    
 33InBlock.gif        public static void StoreFirstPilot(ObjectContainer db)
 34ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 35InBlock.gif            Pilot pilot1 = new Pilot("Michael Schumacher"100);
 36InBlock.gif            db.Set(pilot1);
 37InBlock.gif            Console.WriteLine("Stored {0}", pilot1);
 38ExpandedSubBlockEnd.gif        }

 39InBlock.gif    
 40InBlock.gif        public static void StoreSecondPilot(ObjectContainer db)
 41ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 42InBlock.gif            Pilot pilot2 = new Pilot("Rubens Barrichello"99);
 43InBlock.gif            db.Set(pilot2);
 44InBlock.gif            Console.WriteLine("Stored {0}", pilot2);
 45ExpandedSubBlockEnd.gif        }

 46InBlock.gif    
 47InBlock.gif        public static void RetrieveAllPilots(ObjectContainer db)
 48ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 49InBlock.gif            Query query = db.Query();
 50InBlock.gif            query.Constrain(typeof(Pilot));
 51InBlock.gif            ObjectSet result = query.Execute();
 52InBlock.gif            ListResult(result);
 53ExpandedSubBlockEnd.gif        }

 54InBlock.gif    
 55InBlock.gif        public static void RetrievePilotByName(ObjectContainer db)
 56ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 57InBlock.gif            Query query = db.Query();
 58InBlock.gif            query.Constrain(typeof(Pilot));
 59InBlock.gif            query.Descend("_name").Constrain("Michael Schumacher");
 60InBlock.gif            ObjectSet result = query.Execute();
 61InBlock.gif            ListResult(result);
 62ExpandedSubBlockEnd.gif        }

 63InBlock.gif        
 64InBlock.gif        public static void RetrievePilotByExactPoints(ObjectContainer db)
 65ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 66InBlock.gif            Query query = db.Query();
 67InBlock.gif            query.Constrain(typeof(Pilot));
 68InBlock.gif            query.Descend("_points").Constrain(100);
 69InBlock.gif            ObjectSet result = query.Execute();
 70InBlock.gif            ListResult(result);
 71ExpandedSubBlockEnd.gif        }

 72InBlock.gif    
 73InBlock.gif        public static void RetrieveByNegation(ObjectContainer db)
 74ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 75InBlock.gif            Query query = db.Query();
 76InBlock.gif            query.Constrain(typeof(Pilot));
 77InBlock.gif            query.Descend("_name").Constrain("Michael Schumacher").Not();
 78InBlock.gif            ObjectSet result = query.Execute();
 79InBlock.gif            ListResult(result);
 80ExpandedSubBlockEnd.gif        }

 81InBlock.gif    
 82InBlock.gif        public static void RetrieveByConjunction(ObjectContainer db)
 83ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 84InBlock.gif            Query query = db.Query();
 85InBlock.gif            query.Constrain(typeof(Pilot));
 86InBlock.gif            Constraint constr = query.Descend("_name")
 87InBlock.gif                    .Constrain("Michael Schumacher");
 88InBlock.gif            query.Descend("_points")
 89InBlock.gif                    .Constrain(99).And(constr);
 90InBlock.gif            ObjectSet result = query.Execute();
 91InBlock.gif            ListResult(result);
 92ExpandedSubBlockEnd.gif        }

 93InBlock.gif    
 94InBlock.gif        public static void RetrieveByDisjunction(ObjectContainer db)
 95ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 96InBlock.gif            Query query = db.Query();
 97InBlock.gif            query.Constrain(typeof(Pilot));
 98InBlock.gif            Constraint constr = query.Descend("_name")
 99InBlock.gif                    .Constrain("Michael Schumacher");
100InBlock.gif            query.Descend("_points")
101InBlock.gif                    .Constrain(99).Or(constr);
102InBlock.gif            ObjectSet result = query.Execute();
103InBlock.gif            ListResult(result);
104ExpandedSubBlockEnd.gif        }

105InBlock.gif    
106InBlock.gif        public static void RetrieveByComparison(ObjectContainer db)
107ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
108InBlock.gif            Query query = db.Query();
109InBlock.gif            query.Constrain(typeof(Pilot));
110InBlock.gif            query.Descend("_points")
111InBlock.gif                    .Constrain(99).Greater();
112InBlock.gif            ObjectSet result = query.Execute();
113InBlock.gif            ListResult(result);
114ExpandedSubBlockEnd.gif        }

115InBlock.gif    
116InBlock.gif        public static void RetrieveByDefaultFieldValue(ObjectContainer db)
117ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
118InBlock.gif            Pilot somebody = new Pilot("Somebody else"0);
119InBlock.gif            db.Set(somebody);
120InBlock.gif            Query query = db.Query();
121InBlock.gif            query.Constrain(typeof(Pilot));
122InBlock.gif            query.Descend("_points").Constrain(0);
123InBlock.gif            ObjectSet result = query.Execute();
124InBlock.gif            ListResult(result);
125InBlock.gif            db.Delete(somebody);
126ExpandedSubBlockEnd.gif        }

127InBlock.gif        
128InBlock.gif        public static void RetrieveSorted(ObjectContainer db)
129ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
130InBlock.gif            Query query = db.Query();
131InBlock.gif            query.Constrain(typeof(Pilot));
132InBlock.gif            query.Descend("_name").OrderAscending();
133InBlock.gif            ObjectSet result = query.Execute();
134InBlock.gif            ListResult(result);
135InBlock.gif            query.Descend("_name").OrderDescending();
136InBlock.gif            result = query.Execute();
137InBlock.gif            ListResult(result);
138ExpandedSubBlockEnd.gif        }

139InBlock.gif    
140InBlock.gif        public static void ClearDatabase(ObjectContainer db)
141ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
142InBlock.gif            ObjectSet result = db.Get(typeof(Pilot));
143InBlock.gif            foreach (object item in result)
144ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
145InBlock.gif                db.Delete(item);
146ExpandedSubBlockEnd.gif            }

147ExpandedSubBlockEnd.gif        }

148ExpandedSubBlockEnd.gif    }

149ExpandedBlockEnd.gif}

150None.gif

转载于:https://www.cnblogs.com/JackyXu/archive/2006/11/13/559747.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值