You are here: Object Lifecycle > Querying > SODA Query > Building SODA Queries

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
private static void retrieveAllPilots()  {
    ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME);
    try  {
      Query query = container.query();
      query.constrain(Pilot.class);
      ObjectSet result = query.execute();
      listResult(result);
    } finally  {
      container.close();
    }
  }

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
private static void retrievePilotByName(ObjectContainer container)  {
    Query query = container.query();
    query.constrain(Pilot.class);
    query.descend("name").constrain("Michael Schumacher");
    ObjectSet result = query.execute();
    listResult(result);
  }

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
private static void retrievePilotByExactPoints(
      ObjectContainer container)  {
    Query query = container.query();
    query.constrain(Pilot.class);
    query.descend("points").constrain(new Integer(100));
    ObjectSet result = query.execute();
    listResult(result);
  }

Download example code:

Java