Retrieving Structured Objects

QBE

To retrieve all cars a simple 'blank' prototype can be used.

StructuredExample.java: retrieveAllCarsQBE
1public static void retrieveAllCarsQBE(ObjectContainer db) { 2 Car proto=new Car(null); 3 ObjectSet result=db.get(proto); 4 listResult(result); 5 }

You can also query for all pilots, of course.

StructuredExample.java: retrieveAllPilotsQBE
1public static void retrieveAllPilotsQBE(ObjectContainer db) { 2 Pilot proto=new Pilot(null,0); 3 ObjectSet result=db.get(proto); 4 listResult(result); 5 }

Now let's initialize the prototype to specify all cars driven by Rubens Barrichello.

StructuredExample.java: retrieveCarByPilotQBE
1public static void retrieveCarByPilotQBE( 2 ObjectContainer db) { 3 Pilot pilotproto=new Pilot("Rubens Barrichello",0); 4 Car carproto=new Car(null); 5 carproto.setPilot(pilotproto); 6 ObjectSet result=db.get(carproto); 7 listResult(result); 8 }

What about retrieving a pilot by car? You simply don't need that -if you already know the car, you can simply access the pilot field directly.

StructuredExample.java: retrieveCarByPilotQBE
1public static void retrieveCarByPilotQBE( 2 ObjectContainer db) { 3 Pilot pilotproto=new Pilot("Rubens Barrichello",0); 4 Car carproto=new Car(null); 5 carproto.setPilot(pilotproto); 6 ObjectSet result=db.get(carproto); 7 listResult(result); 8 }

Native Queries

Using native queries with constraints on deep structured objects is straightforward, you can do it just like you would in plain other code.

Let's constrain our query to only those cars driven by a Pilot with a specific name:

StructuredExample.java: retrieveCarsByPilotNameNative
1public static void retrieveCarsByPilotNameNative(ObjectContainer db) { 2 final String pilotName = "Rubens Barrichello"; 3 ObjectSet results = db.query(new Predicate<Car>() { 4 public boolean match(Car car){ 5 return car.getPilot().getName().equals(pilotName); 6 } 7 }); 8 listResult(results); 9 }

SODA Query API

In order to use SODA for querying for a car given its pilot's name you have to descend two levels into our query.

StructuredExample.java: retrieveCarByPilotNameQuery
1public static void retrieveCarByPilotNameQuery( 2 ObjectContainer db) { 3 Query query=db.query(); 4 query.constrain(Car.class); 5 query.descend("pilot").descend("name") 6 .constrain("Rubens Barrichello"); 7 ObjectSet result=query.execute(); 8 listResult(result); 9 }

You can also constrain the pilot field with a prototype to achieve the same result.

StructuredExample.java: retrieveCarByPilotProtoQuery
1public static void retrieveCarByPilotProtoQuery( 2 ObjectContainer db) { 3 Query query=db.query(); 4 query.constrain(Car.class); 5 Pilot proto=new Pilot("Rubens Barrichello",0); 6 query.descend("pilot").constrain(proto); 7 ObjectSet result=query.execute(); 8 listResult(result); 9 }

Descending into a query provides you with another query. Starting out from a query root you can descend in multiple directions. In practice this is the same as ascending from one child to a parent and descending to another child. The queries turn one-directional references in objects into true relations. Here is an example that queries for "a Pilot that is being referenced by a Car, where the Car model is 'Ferrari'":

StructuredExample.java: retrievePilotByCarModelQuery
1public static void retrievePilotByCarModelQuery(ObjectContainer db) { 2 Query carquery=db.query(); 3 carquery.constrain(Car.class); 4 carquery.descend("model").constrain("Ferrari"); 5 Query pilotquery=carquery.descend("pilot"); 6 ObjectSet result=pilotquery.execute(); 7 listResult(result); 8 }