紧接上篇:db4o_8.0对象数据库官方文档翻译_学习笔记三

4. Querying(查询)

db4o supplies three querying systems, Query-By-Example (QBE) Native Queries (NQ), and the SODA API. In the previous chapter, you were briefly introduced to Query By Example(QBE).

Query-By-Example (QBE) is appropriate as a quick start for users who are still acclimating to storing and retrieving objects with db4o.

Native Queries (NQ) are the main db4o query interface, recommended for general use.

SODA is the underlying internal API. It is provided for backward compatibility and it can be useful for dynamic generation of queries, where NQ are too strongly typed.

db4o支持三种查询系统:样本查询(Query-By-Example,通常缩写为QBE),原生查询(Native Queries,缩写为NQ)和SODA API。在前面的章节中,我们概括性地介绍了样本查询。

样本查询(Query-By-Example)学习起来更加快速,对于刚开始学习db4o存取对象的用户非常有效。相对来说,更容易理解吧。

原生查询(NQ)是db4o主要的常用查询接口。

SODA是底层的内部API。它提供了向后兼容性,并能用于查询的动态生成,而使用NQ来完成相同功能却需要过多的编写工作。

4.1. Query by Example (QBE)

When using Query By Example (QBE) you provide db4o with a template object. db4o will return all of the objects which match all non-default field values. This is done via reflecting all of the fields and building a query expression where all non-default-value fields are combined with AND expressions.

Here's an example from the previous chapter:

在使用QBE时,你需要提供给db4o一个模板对象。db4o将返回所有匹配此模板的无默认字段值(non-default field values)的对象。这些工作是通过反射所有字段、创建查询表达式来完成的,在查询表达式中所有的无默认值字段都被AND表达式连接在一起。下面提供了上一章中的示例:

// retrievePilotByName

Pilot proto = new Pilot("Michael Schumacher", 0);

ObjectSet result = db.queryByExample(proto);

listResult(result);

Querying this way has some obvious limitations:

- db4o must reflect all members of your example object.

- You cannot perform advanced query expressions. (AND, OR, NOT, etc.)

- You cannot constrain on values like 0 (integers), "" (empty strings), or nulls (reference types) because they would be interpreted as unconstrained.

- You need to be able to create objects without initialized fields. That means you can not initialize fields where they are declared. You can not enforce contracts that objects of a class are only allowed in a well-defined initialized state.

- You need a constructor to create objects without initialized fields.

To get around all of these constraints, db4o provides the Native Query (NQ) system.

使用此方式查询存在着一些明显的局限性:
- db4o必须反射所有样本对象的成员。
- 你不能执行高级的查询表达式。(AND,OR,NOT等)
- 你不能针对象0(整数)这样的字段值、""(空白字符串)或者null(引用类型)进行约束限制。因为它们都将被解释为不受约束限制的。
- 你必需能够使用无初始化字段的方式来创建对象,这意味着你不能在字段声明时对其进行初始化。最难的是,你不能强行约定某个类的对象只能处于这种定义良好的初始化状态。
- 你需要一个没有任何初始化字段的构造函数来创建对象。

为了绕过这些约束,db4o提供了原生查询(NQ)系统。

4.2. Native Queries(原生查询)

Wouldn't it be nice to pose queries in the programming language that you are using? Wouldn't it be nice if all your query code was 100% typesafe, 100% compile-time checked and 100% refactorable?

Wouldn't it be nice if the full power of object-orientation could be used by calling methods from within queries? Enter Native Queries.

Native queries are the main db4o query interface and they are the recommended way to query databases from your application. Because native queries simply use the semantics of your programming language, they are perfectly standardized and a safe choice for the future.

Native Queries are available for all platforms supported by db4o.

在你正使用的编程语言中放置查询,这难道不好吗?如果你的查询代码100%的类型安全、100%在编译时检查、100%可重构,这难道不妙吗?如果所有面向对象的优势都能被用于在查询中调用方法,这不是很好吗?如果你正希望这样,那么请使用原生查询。

原生查询是db4o的主要查询接口,它是查询数据库的推荐方式。由于原生查询简单地使用了编程语言的语法,因此它是非常标准化的,并且是一种面向未来的安全选择。

原生查询在所有db4o支持的平台下均可用。

4.2.1. Concept

The concept of native queries is taken from the following two papers:

原生查询的概念出自下面的两篇文章:

Cook/Rosenberger, Native Queries for Persistent Objects, A Design White Paper

Cook/Rai, Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

4.2.2. Principle(原则)

Native Queries provide the ability to run one or more lines of code against all instances of a class.Native query expressions should return true to mark specific instances as part of the result set. db4o will attempt to optimize native query expressions and run them against indexes and without instantiating actual objects, where this is possible.

原生查询具备根据某个类的所有实例来运行一行或是多行代码的能力。原生查询表达式返回true来表示结果集中存在着某些特定实例。db4o将尝试优化原生查询表达式,并依靠索引运行表达式,而无需实例化实际的对象。

4.2.3. Simple Example(简单实例讲解)

Let's look at how a simple native query will look like in some of the programming languages and dialects that db4o supports:

让我们看以下的简单原生查询示例,它看起来酷似某些编程语言和db4o支持的方言(dialects)。

C# .NET

IList <Pilot> pilots = db.Query <Pilot> (delegate(Pilot pilot) {

return pilot.Points == 100;

});

Java JDK 5

List <Pilot> pilots = db.query(new Predicate<Pilot>() {

public boolean match(Pilot pilot) {

return pilot.getPoints() == 100;

}

});

Public Class PilotHundredPoints

Inherits Predicate

Public Function Match (pilot As Pilot) as Boolean

If pilot.Points = 100 Then

Return True

Else

Return False

End Function

End Class

A side note on the above syntax:

For all dialects without support for generics, Native Queries work by convention. A class that extends the com.db4o.Predicate class is expected to have a boolean #match() method with one parameter to describe the class extent:

请注意在上面的语法中:对于所有不支持类属的方言,NQ遵守约定工作。某个扩展自com.db4o.Predicate的类需要有一个boolean #match()方法,此方法接受一个描述类范围的参数:

boolean match(Pilot candidate);

When using native queries, don't forget that modern integrated development environments (IDEs) can do all the typing work around the native query expression for you, if you use templates and autocompletion.

Here is how to configure a Native Query template with Eclipse 3.1:

From the menu, choose Window + Preferences + Java + Editor + Templates + New

As the name type "nq". Make sure that "java" is selected as the context on the right. Paste the following into the pattern field:

在使用NQ时,不要忘记如果你使用模板和自动完成技术的话,可用现代化集成开发环境(IDEs)来帮你完成所有原生表达式相关的代码录入工作。

下面是如何在Eclipse3.1中配置原生查询模板:
从菜单中选择Window->Preferences->Java->Editor->Templates->New。

我们可用将它起名为"nq"。确认你已经在右侧的上下文(context)中选择了"java"。粘贴下列代码到模板输入域:

List <${extent}> list = db.query(new Predicate <${extent}> () {

public boolean match(${extent} candidate){

return true;

}

});

Now you can create a native query with three keys: n + q + Control-Space.

Similar features are available in most modern IDEs.

现在,你就能够使用n+q+Control-Space这三个组合键来创建原生查询了。在大多数IDE中都有类似的特性。

4.2.4. Advanced Example

For complex queries, the native syntax is very precise and quick to write. Let's compare to a SODA query that finds all pilots with a given name or a score within a given range:

为了进行复杂的查询,原生语法是非常精确并且书写快捷的。让我们将NQ和SODA查询进行一下比较,查询目标是发现所有匹配给定名字或者成绩在指定范围中的pilot(飞行员):

// storePilots

db.store(new Pilot("Michael Schumacher",100));

db.store(new Pilot("Rubens Barrichello",99));

// retrieveComplexSODA

Query query=db.query();

query.constrain(Pilot.class);

Query pointQuery=query.descend("points");

query.descend("name").constrain("Rubens Barrichello")

.or(pointQuery.constrain(99).greater()

.and(pointQuery.constrain(199).smaller()));

ObjectSet result=query.execute();

listResult(result);

OUTPUT:

2

Michael Schumacher/100

Rubens Barrichello/99

Here is how the same query will look like with native query syntax, fully accessible to autocompletion, refactoring and other IDE features, fully checked at compile time:

下面的示例展示了如何同一个查询在不同语言中使用原生查询语法的相似性,它们完全可以使用自动完成功能、重构和其他IDE特性,并在编译时作检查:

C# .NET 2.0

IList <Pilot> result = db.Query<Pilot> (delegate(Pilot pilot) {

return pilot.Points > 99

&& pilot.Points < 199

|| pilot.Name == "Rubens Barrichello";

});

Java JDK 5

List <Pilot> result = db.query(new Predicate<Pilot>() {

public boolean match(Pilot pilot) {

return pilot.getPoints() > 99

&& pilot.getPoints() < 199

|| pilot.getName().equals("Rubens Barrichello");

}

});

4.2.5. Arbitrary Code(任意代码)

Basically that's all there is to know about native queries to be able to use them efficiently. In principle you can run arbitrary code as native queries, you just have to be very careful with side effects -especially those that might affect persistent objects.

Let's run an example that involves some more of the language features available.

基本上,这就是NQ之所以能够被高效使用的原因。原则上,你可以将任意代码作为NQ来运行,但你需要非常小心某些方面的影响-尤其是那些可能对持久化对象发生作用的影响。让我们运行一个示例来调用更多可用的语言特性:

// retrieveArbitraryCodeNQ

final int[] points={1,100};

List<Pilot> result=db.query(new Predicate<Pilot>() {

public boolean match(Pilot pilot) {

for (int point : points) {

if (pilot.getPoints() == point) {

return true;

}

}

return pilot.getName().startsWith("Rubens");

}

});

listResult(result);

OUTPUT:

2

Michael Schumacher/100

Rubens Barrichello/99

4.2.6. Native Query Performance  (原生查询的性能)

One drawback of native queries has to be pointed out: Under the hood db4o tries to analyze native queries to convert them to SODA. This is not possible for all queries. For some queries it is very difficult to analyze the flowgraph. In this case db4o will have to instantiate some of the persistent objects to actually run the native query code. db4o will try to analyze parts of native query expressions to keep object instantiation to the minimum.

The development of the native query optimization processor will be an ongoing process in a close dialog with the db4o community. Feel free to contribute your results and your needs by providing feedback to our db4o forums(Forums are accessible through free db4o membership).

The current state of the query optimization process is detailed in the chapter on Native QueryOptimizationWith the current implementation, all above examples will run optimized, except for the "Arbitrary Code" example - we are working on it.

这里将指出原生查询的一个缺点:在内部,db4o尝试分析原生查询并将其转换为SODA。这并不适用于所有的查询。对于一些查询来讲,分析流动图表(flowgraph)是非常困难的。在这种情况下,db4o将不得不实例化一些持久化对象来真正地执行原生查询代码。db4o会尝试分析原生查询表达式的组成部分,来保持对象实例化的最小化。

原生查询优化处理器的开发将是一个持续不断地与db4o社区进行亲密对话的过程。开发者可以自愿捐献开发成果并通过提交反馈给我们db4o论坛的方式贡献需求。

查询优化过程当前的状况在原生查询优化一章中进行详细描述。 通过使用目前的查询优化器,上面所有的示例都能够被优化运行,除了在"任意代码"中的示例- 我们正在解决此问题。

4.2.7. Full source(所有代码)

package com.db4odoc.f1.chapter1;

import com.db4o.Db4oEmbedded;

import com.db4o.ObjectContainer;

import com.db4o.ObjectSet;

import com.db4o.query.Predicate;

import com.db4o.query.Query;

import com.db4odoc.f1.Util;

import java.util.List;

public class NQExample extends Util {

final static String DB4OFILENAME =

System.getProperty("user.home") + "/formula1.db4o";

public static void main(String[] args) {

ObjectContainer db=Db4oEmbedded.openFile(Db4oEmbedded

.newConfiguration(), DB4OFILENAME);

try {

storePilots(db);

retrieveComplexSODA(db);

retrieveComplexNQ(db);

retrieveArbitraryCodeNQ(db);

clearDatabase(db);

}

finally {

db.close();

}

}

public static void storePilots(ObjectContainer db) {

db.store(new Pilot("Michael Schumacher",100));

db.store(new Pilot("Rubens Barrichello",99));

}

public static void retrieveComplexSODA(ObjectContainer db) {

Query query=db.query();

query.constrain(Pilot.class);

Query pointQuery=query.descend("points");

query.descend("name").constrain("Rubens Barrichello")

.or(pointQuery.constrain(99).greater()

.and(pointQuery.constrain(199).smaller()));

ObjectSet result=query.execute();

listResult(result);

}

public static void retrieveComplexNQ(ObjectContainer db) {

List<Pilot> result=db.query(new Predicate<Pilot>() {

public boolean match(Pilot pilot) {

return pilot.getPoints()>99

&& pilot.getPoints()<199

|| pilot.getName().equals("Rubens Barrichello");

}

});

listResult(result);

}

public static void retrieveArbitraryCodeNQ(ObjectContainer db) {

final int[] points={1,100};

List<Pilot> result=db.query(new Predicate<Pilot>() {

public boolean match(Pilot pilot) {

for (int point : points) {

if (pilot.getPoints() == point) {

return true;

}

}

return pilot.getName().startsWith("Rubens");

}

});

listResult(result);

}

public static void clearDatabase(ObjectContainer db) {

ObjectSet result=db.queryByExample(Pilot.class);

while(result.hasNext()) {

db.delete(result.next());

}

}

}

4.3. SODA Query API(SODA查询API)

The SODA query API is db4o's low level querying API, allowing direct access to nodes of query graphs. Since SODA uses strings to identify fields, it is neither perfectly typesafe nor compile-time checked and it also is quite verbose to write.

For most applications Native Querieswill be the better querying interface. However there can be applications where dynamic generation of queries is required, that's why SODA is explained here.

SODA查询API是db4o的低级查询API,它允许直接访问查询图表(query graphs)的节点。由于SODA使用字符串标识字段,因此它并不是非常类型安全的,也不是编译时可检查的,并且编写的代码冗长。

对于大多数应用来讲,原生查询将是更好的查询接口。但是,由于存在着需要动态生成查询的应用,这便是我们为什么在这里解释SODA的原因。

4.3.1. Simple queries(简单查询)

Let's see how our familiar QBE queries are expressed with SODA. A new Query object is created through the #query() method of the ObjectContainer and we can add Constraint instances to it. To find all Pilot instances, we constrain the query with the Pilot class object.

让我们看一下我们熟知的QBE查询是如何用SODA表示的。一个新的Query对象通过ObjectContainer的#query()方法创建,我们可用在其上添加Constraint类实例。为了找到所有的Pilot实例,我们对Pilot类对象的查询进行了约束限制。

// retrieveAllPilots

Query query=db.query();

query.constrain(Pilot.class);

ObjectSet result=query.execute();

listResult(result);

OUTPUT:

2

Michael Schumacher/100

Rubens Barrichello/99

Basically, we are exchanging our 'real' prototype for a meta description of the objects we'd like to hunt down: a query graph made up of query nodes and constraints. A query node is a placeholder for a candidate object, a constraint decides whether to add or exclude candidates from the result.

Our first simple graph looks like this.

基本上,我们正在将"真正的"原型(prototype)交换为我们希望捕捉到的对象元描述(meta description):一个查询图表由多个查询节点和约束构成。每个查询节点都是一个存放候选对象的地方,每个约束则标识了是否从结果集中添加还是排除候选者。

我们的第一个简单图表:

We're just asking any candidate object (here: any object in the database) to be of type Pilot to aggregate our result.

To retrieve a pilot by name, we have to further constrain the candidate pilots by descending to their name field and constraining this with the respective candidate String.

我们正在寻找Pilot类型的候选对象(在这里是数据库中的任意对象),并将其聚会到我们的查询结果中。

为了通过名字获取某个pilot,我们将通过向下访问它们的名字字段、使用特殊的候选字符串来限制其取值的方式进一步限定候选对象:

// retrievePilotByName

Query query=db.query();

query.constrain(Pilot.class);

query.descend("name").constrain("Michael Schumacher");

ObjectSet result=query.execute();

listResult(result);

OUTPUT:

1

Michael Schumacher/100

What does #descend mean here? Well, just as we did in our 'real' prototypes, we can attach constraints to child members of our candidates.

"descend"(深层访问)是什么意思?那就是在我们"真正的"原型中将约束分派给候选对象的子成员

So a candidate needs to be of type Pilot and have a member named 'name' that is equal to the given String to be accepted for the result.Note that the class constraint is not required: If we left it out, we would query for all objects that contain a 'name' member with the given value. In most cases this will not be the desired behavior, though.

Finding a pilot by exact points is analogous.We just have to cross the Java primitive/object divide.

所以,一个候选对象必须是Pilot类型、且具有一个name字段,并且"name"字段值为给定字符串,才能出现在结果集中。请注意,类约束不是必需的:如果我们不设置它,那么便会查询到所有"name"字段值为给定字符串的对象。在多数情况下,这并不是我们想要的行为。

通过精确的point值来查询pilot是与上面相似的。我们跨越Java私有类型(primitive)和对象进行划分。

// retrievePilotByExactPoints

Query query=db.query();

query.constrain(Pilot.class);

query.descend("points").constrain(100);

ObjectSet result=query.execute();

listResult(result);

OUTPUT:

1

Michael Schumacher/100

4.3.2. Advanced queries(高级查询)

Now there are occasions when we don't want to query for exact field values, but rather for value ranges, objects not containing given member values, etc. This functionality is provided by the Constraint API.

First, let's negate a query to find all pilots who are not Michael Schumacher:

此功能适用于我们不想查询精确字段值时,而是取值范围、不包含给定成员值的对象等情况时。它提供了Constraint API来实现之。

首先,让我们编写一个对名字不是Michael Schumacher的pilot的查询:

// retrieveByNegation

Query query=db.query();

query.constrain(Pilot.class);

query.descend("name").constrain("Michael Schumacher").not();

ObjectSet result=query.execute();

listResult(result);

OUTPUT:

1

Rubens Barrichello/99

Where there is negation, the other boolean operators can't be too far.

在这种反向查询时,布尔操作很常见。

// retrieveByConjunction

Query query=db.query();

query.constrain(Pilot.class);

Constraint constr=query.descend("name")

.constrain("Michael Schumacher");

query.descend("points")

.constrain(99).and(constr);

ObjectSet result=query.execute();

listResult(result);

OUTPUT:

0

// retrieveByDisjunction

Query query=db.query();

query.constrain(Pilot.class);

Constraint constr=query.descend("name")

.constrain("Michael Schumacher");

query.descend("points")

.constrain(99).or(constr);

ObjectSet result=query.execute();

listResult(result);

OUTPUT:

2

Michael Schumacher/100

Rubens Barrichello/99

We can also constrain to a comparison with a given value.

我们也可以添加针对给定值进行比较的约束。

// retrieveByComparison

Query query=db.query();

query.constrain(Pilot.class);

query.descend("points")

.constrain(99).greater();

ObjectSet result=query.execute();

listResult(result);

OUTPUT:

1

Michael Schumacher/100

The query API also allows to query for field default values.

这种查询API还能够查询字段默认值(注意与QBE方式的差别)

// retrieveByDefaultFieldValue

Pilot somebody=new Pilot("Somebody else",0);

db.store(somebody);

Query query=db.query();

query.constrain(Pilot.class);

query.descend("points").constrain(0);

ObjectSet result=query.execute();

listResult(result);

db.delete(somebody);

OUTPUT:

1

Somebody else/0

It is also possible to have db4o sort the results.

也可以让db4o对结果集进行排序。

// retrieveSorted

Query query=db.query();

query.constrain(Pilot.class);

query.descend("name").orderAscending();

ObjectSet result=query.execute();

listResult(result);

query.descend("name").orderDescending();

result=query.execute();

listResult(result);

OUTPUT:

2

Michael Schumacher/100

Rubens Barrichello/99

2

Rubens Barrichello/99

Michael Schumacher/100

All these techniques can be combined arbitrarily, of course. Please try it out. There still may be cases left where the predefined query API constraints may not be sufficient - don't worry, you can always let db4o run any arbitrary code that you provide in an Evaluation. Evaluations will be discussed in a laterchapter.

To prepare for the next chapter, let's clear the database.

当然,以上这些技术都能够任意组合使用。请大家自行尝试。也许预定义的查询API约束并不能满足需要,请不要着急,你可以让db4o执行在Evaluation(评估)中提供的任意代码。Evaluation将在最后一章中讨论。

为了下一章做准备,让我们清空数据库。

// clearDatabase

ObjectSet result=db.queryByExample(Pilot.class);

while(result.hasNext()) {

db.delete(result.next());

}

OUTPUT:

4.3.3. Conclusion(总结)

Now you have been provided with the following alternative approaches to query db4o databases: Query-By-Example,.? net LINQ, Native Queries, SODA.

Which one is the best to use? Some hints:

- Native queries are targeted to be the primary interface for db4o, so they should be preferred.

- With the current state of the db4o query optimizer there may be queries that will execute faster in SODA style, so it can be used to tune applications. SODA can also be more convenient for constructing dynamic queries at runtime.

- Query-By-Example is nice for simple one-liners, but restricted in functionality. If you like this approach, use it as long as it suits your application's needs.

Of course you can mix these strategies as needed.

We have finished our walkthrough and seen the various ways db4o provides to pose queries. But our domain model is not complex at all, consisting of one class only. Let's have a look at the way db4o handles object associations in the next chapter.

到此为止,你已经了解了以下三种查询db4o数据库的方式:样本查询(QBE)、原生查询(NQ)、SODA。

哪一种是最好的呢?下面给出了一些提示:
- 原生查询的目标是成为db4o的首要接口,因此它应该作为首选。
- 鉴于当前原生查询优化器的状态,某些查询使用SODA风格能够获得更快的执行速度,因此它被用于对应用进行优化。SODA对于在运行时构造动态查询也是非常方便的。
- 样本查询是非常简单的单行查询,但在功能上存在局限。如果你喜欢这种方式,并且它能够满足你的应用要求的话,仍可以使用。

当然,你也可以按需混合上面的风格。

到此为止,我们已经完成了关于查询的学习,并且看到了多种db4o提供的查询。但我们的所定义的类模型一点都不复杂,仅仅由一个类构成。在下一章,我们将看到db4o是如何处理对象关联。

4.3.4. Full source(所有源代码)

package com.db4odoc.f1.chapter1;

import com.db4o.*;

import com.db4o.query.Constraint;

import com.db4o.query.Query;

import com.db4odoc.f1.*;

public class QueryExample extends Util {

final static String DB4OFILENAME =

System.getProperty("user.home") + "/formula1.db4o";

public static void main(String[] args) {

ObjectContainer db=Db4oEmbedded.openFile(Db4oEmbedded

.newConfiguration(), DB4OFILENAME);

try {

storeFirstPilot(db);

storeSecondPilot(db);

retrieveAllPilots(db);

retrievePilotByName(db);

retrievePilotByExactPoints(db);

retrieveByNegation(db);

retrieveByConjunction(db);

retrieveByDisjunction(db);

retrieveByComparison(db);

retrieveByDefaultFieldValue(db);

retrieveSorted(db);

clearDatabase(db);

}

finally {

db.close();

}

}

public static void storeFirstPilot(ObjectContainer db) {

Pilot pilot1=new Pilot("Michael Schumacher",100);

db.store(pilot1);

System.out.println("Stored "+pilot1);

}

public static void storeSecondPilot(ObjectContainer db) {

Pilot pilot2=new Pilot("Rubens Barrichello",99);

db.store(pilot2);

System.out.println("Stored "+pilot2);

}

public static void retrieveAllPilots(ObjectContainer db) {

Query query=db.query();

query.constrain(Pilot.class);

ObjectSet result=query.execute();

listResult(result);

}

public static void retrievePilotByName(ObjectContainer db) {

Query query=db.query();

query.constrain(Pilot.class);

query.descend("name").constrain("Michael Schumacher");

ObjectSet result=query.execute();

listResult(result);

}

public static void retrievePilotByExactPoints(

ObjectContainer db) {

Query query=db.query();

query.constrain(Pilot.class);

query.descend("points").constrain(100);

ObjectSet result=query.execute();

listResult(result);

}

public static void retrieveByNegation(ObjectContainer db) {

Query query=db.query();

query.constrain(Pilot.class);

query.descend("name").constrain("Michael Schumacher").not();

ObjectSet result=query.execute();

listResult(result);

}

public static void retrieveByConjunction(ObjectContainer db) {

Query query=db.query();

query.constrain(Pilot.class);

Constraint constr=query.descend("name")

.constrain("Michael Schumacher");

query.descend("points")

.constrain(99).and(constr);

ObjectSet result=query.execute();

listResult(result);

}

public static void retrieveByDisjunction(ObjectContainer db) {

Query query=db.query();

query.constrain(Pilot.class);

Constraint constr=query.descend("name")

.constrain("Michael Schumacher");

query.descend("points")

.constrain(99).or(constr);

ObjectSet result=query.execute();

listResult(result);

}

public static void retrieveByComparison(ObjectContainer db) {

Query query=db.query();

query.constrain(Pilot.class);

query.descend("points")

.constrain(99).greater();

ObjectSet result=query.execute();

listResult(result);

}

public static void retrieveByDefaultFieldValue(

ObjectContainer db) {

Pilot somebody=new Pilot("Somebody else",0);

db.store(somebody);

Query query=db.query();

query.constrain(Pilot.class);

query.descend("points").constrain(0);

ObjectSet result=query.execute();

listResult(result);

db.delete(somebody);

}

public static void retrieveSorted(ObjectContainer db) {

Query query=db.query();

query.constrain(Pilot.class);

query.descend("name").orderAscending();

ObjectSet result=query.execute();

listResult(result);

query.descend("name").orderDescending();

result=query.execute();

listResult(result);

}

public static void clearDatabase(ObjectContainer db) {

ObjectSet result=db.queryByExample(Pilot.class);

while(result.hasNext()) {

db.delete(result.next());

}

}

}

db4o_8.0对象数据库官方文档翻译_学习笔记四相关推荐

  1. db4o_8.0对象数据库官方文档翻译_学习笔记三

    紧接上篇:db4o_8.0对象数据库官方文档翻译_学习笔记二 3. Object Manager Enterprise Overview(OME视图)即OME插件的使用 If you did not  ...

  2. SSRS:使用SQL2008教程学习Reporting Services之数据库AdventureWorks2008问题_学习笔记1

    首先声明我是菜鸟,刚开始学习Reporting Services.在学习教程中的一点笔记. 从SQL2005开始,微软就提供了强大的Reporting Services功能,的确好用,对于经常需要出复 ...

  3. mysql 9.0创建数据库_PHP与MySQL学习笔记9:创建Web数据库

    1.在服务器上部署MySQL服务基本步骤合注意点 1)安装MySQL(命令安装.安装包安装等) 2)考虑是否需要一个独立的操作系统用户权限来运行MySQL程序. 3)路径的设置 4)root密码 (附 ...

  4. DHCP服务_学习笔记

    DHCP服务_学习笔记 DHCP(Dynamic Host Configuration Protocol):动态主机配置协议 Lease:租约    续租时间需要是租期时间的一半 UDP协议: Ser ...

  5. 韩顺平php可爱屋源码_韩顺平_php从入门到精通_视频教程_第20讲_仿sohu主页面布局_可爱屋首页面_学习笔记_源代码图解_PPT文档整理...

    韩顺平_php从入门到精通_视频教程_第20讲_仿sohu首页面布局_可爱屋首页面_学习笔记_源代码图解_PPT文档整理 对sohu页面的分析 注释很重要 经验:写一点,测试一点,这是一个很好的方法. ...

  6. 友盟统计+渠道包_学习笔记

    友盟统计+渠道包_学习笔记 资料: 官网:https://developer.umeng.com/docs/66632/detail/66889#h3-u5E38u89C1u95EEu9898 视频资 ...

  7. openCV4.0 C++ 快速入门30讲学习笔记(自用 代码+注释)详细版

    课程来源:哔哩哔哩 环境:OpenCV4.5.1 + VS2019 目录 002.图像色彩空间转换 003.图像对象的创建与赋值 004.图像像素的读写操作 005.图像像素的算术操作(加减乘除4种不 ...

  8. 图论01.最短路专题_学习笔记+模板

    图论01.最短路专题_学习笔记+模板 一.定义与性质 ● 需要的前导知识点 路径 最短路 有向图中的最短路.无向图中的最短路 单源最短路.每对结点之间的最短路 ● 最短路的性质 对于边权为正的图,任意 ...

  9. NCBI SRA数据库使用详解----学习笔记

    NCBI SRA数据库使用详解----学习笔记 wxw060709 2019-12-25 15:58:47  1014  收藏 2 分类专栏: 生物信息学 版权 SRA(Sequence ReadAr ...

  10. MySQL高级学习笔记(四)

    文章目录 MySQL高级学习笔记(四) 1. MySql中常用工具 1.1 mysql 1.1.1 连接选项 1.1.2 执行选项 1.2 mysqladmin 1.3 mysqlbinlog 1.4 ...

最新文章

  1. MATLAB_图形学_形态学课程_温馨饭店招牌扣出‘温馨饭店’四个大字
  2. python二元表达式总结
  3. 训练超参数, 出现 Cannot use GPU in CPU-only Caffe 错误?
  4. 再见 Win10!下一代操作系统来了。。
  5. torch.roll() 详解
  6. modbus-rtu qt4-serialport2------micro2440 as host
  7. mysql 存储过程 批量导入数据_sql 利用存储过程批量导入数据
  8. link 和 style 元素在 HTML 文档中的位置
  9. 【Transformer】Transformer中16个注意力头一定要比1个注意力头效果好吗?
  10. 我的天!你竟然不会用IDEA远程调试Tomcat...
  11. Using TFS2010 Build 提示:Silverlight 4 SDK is not installed解决方法
  12. 2019-CS224n-Assignment4
  13. 【PICkit3】PICkit3 Programmer烧写教程
  14. ue4是什么意思_ue4主要是做什么用的
  15. ios 个人苹果开发者账号申请
  16. 相似度系列-5:语义方法:BERTSCORE: EVALUATING TEXT GENERATION WITH BERT
  17. 网站性能指标 - FMP
  18. 如何通过API方式集成金蝶ERP
  19. throttle在程序中的作用
  20. 关于近期工作中遇到的各种问题总结

热门文章

  1. matlab颜色识别提取,matlab实现图像颜色特征提取
  2. R语言作图入门——软件安装,数据导入
  3. 最新苹果CMSV10视频电影网站源码+自适应手机版
  4. 用亿图软件怎么画数据模型图?
  5. matlab画图函数之plot【matlab图行绘制一】
  6. 简单的C语言程序示例
  7. python爬虫requests设置代理ip_干货|Python爬虫如何设置代理IP
  8. chrome书签搜索
  9. 【bb平台刷课记】wireshark结合实例学抓包
  10. 数据可视化分析工具评测: DataEase (开源新贵)VS.帆软 FineBI(老牌产品)