Building SODA Queries

Let's see how simple 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.

QueryExample.java: retrieveAllPilots
01private static void retrieveAllPilots() { 02 ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 03 try { 04 Query query = container.query(); 05 query.constrain(Pilot.class); 06 ObjectSet result = query.execute(); 07 listResult(result); 08 } finally { 09 container.close(); 10 } 11 }

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.

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.

QueryExample.java: retrievePilotByName
1private static void retrievePilotByName(ObjectContainer container) { 2 Query query = container.query(); 3 query.constrain(Pilot.class); 4 query.descend("name").constrain("Michael Schumacher"); 5 ObjectSet result = query.execute(); 6 listResult(result); 7 }

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

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.

QueryExample.java: retrievePilotByExactPoints
1private static void retrievePilotByExactPoints( 2 ObjectContainer container) { 3 Query query = container.query(); 4 query.constrain(Pilot.class); 5 query.descend("points").constrain(new Integer(100)); 6 ObjectSet result = query.execute(); 7 listResult(result); 8 }