Quantcast
Channel: Gamlor
Viewing all articles
Browse latest Browse all 10

db4o: Queries in Java or Queries Without LINQ

$
0
0

Before I continue with client-server concurrency I explain how to run queries against a db4o database without LINQ. Most of the stuff in db4o works on every platform. The API is nearly the same in Java and .NET, except the different naming-convections. The lucky .NET developers have one big advantage over Java, they have LINQ which is just awesome. The less lucky Java or C# 2.0 developers have to use other methods. So I’ll give an overview over the alternative query-methods. For this post I use Java instead of C# to avoid using LINQ by accident ;)

db4o-java-bff

(All posts of this series: the basics, activation, object-identity, transactions, persistent classes, single container concurrency, Queries in Java, C# 2.0, client-server concurrency, transparent persistence, adhoc query tools)

Native Queries

When you hear ‘Native Queries’ you might think that it is something like SQL. The language which is ‘native’ to the database. You’re wrong. It means that it’s ‘native’ to your programming language. So you write queries just as Java-Code. Native queries are in my opinion the best alternative to LINQ. Basically you pass a inner class (poor man’s closures) to the query-method. There you implement which criteria have to be fulfilled. A simple example:

List<SimpleObject> result = db.query(new Predicate<SimpleObject>() {
    @Override
    public boolean match(SimpleObject o) {
        return o.getNumber()>2;
    }
});
 

So this quite easy and natural. You just write your condition in the match-method of a predicate. A more complex example which also sorts the result:

List<ComplexObject> result2 = db.query(new Predicate<ComplexObject>() {
@Override
public boolean match(ComplexObject o) {
    return o.getVersion()==1
            && o.getKnowsAbout().getNumber()<2
            || o.getMightKnowsAlso()!=null;
}
},new QueryComparator<ComplexObject>() {
    public int compare(ComplexObject complexObject, ComplexObject complexObject1) {
        return complexObject.getKnowsAbout().getName().compareTo(complexObject1.getKnowsAbout().getName());
    }
}); 

Modern Java-IDEs collapse the verbose inner classes to readable little ‘closures’. Therefore it looks nicer in the real world. (Eclipse with lambda4jdt, IntelliJ 9)

native queries

native queries

Query By Example

In this query-type you give the database an object as an example. Then the database returns all objects which are similar to the given object.

An example. We create an new object with name ‘MyObject-3’ and the number 3. Then we pass it to db4o. As result we get all object which have the same name and number.

SimpleObject toSearchFor = new SimpleObject("MyObject-3",3);
final ObjectSet<Object> result1 = db.queryByExample(toSearchFor);

It’s simple but quite limiting. It’s might a suitable solution when you implement some kind of search-forms. Then you just can fill an object with values of the search-form and off you go. But you can imagine the limits. For example you cannot get the objects which have number==0. Because query by example only matches fields which differ from the default-value. For a int 0 is the default and you’re fucked. As far as I know there’s no way to express such condition by example. So you have to use other query-types.

System.out.println("-cannot get the object with Number=0---");
SimpleObject doesnotWork = new SimpleObject(0);
final ObjectSet<Object> result2 = db.queryByExample(doesnotWork);

query be example

query be example

SODA-Queries

Now SODA-Queries is the low level query API for db4o. Normally you don’t touch SODA unless you have some special scenarios. For example when you need to build queries very dynamically. Because of that I just mention it here but don’t give any examples (Maybe another time).

All other query-types, LINQ, Native-Queries and Query By Example are actually translated into SODA-queries. To achieve this db4o uses byte-code analysis and generates then SODA-queries. Simple queries are translated into SODA an run directly on the database. However more complex queries may cannot be optimized. Then db4o actually instantiates the objects and runs the query on the instances. For more details see here: LINQ-Optimization, Native-Query-Optimization

soda queries

soda queries

Conclusion

So, db4o supports a variety of query-types. In my opinion LINQ is the best one, but only available on then most recent .NET framework. Native queries is the second best choice. For special cases query be example might be an alternative. In the end everything is crunched down to SODA-Queries, which is the low level query API. Next time I cover the client-server-concurrency as promised =)

Java-Code: ComplexObject.java, Main.java, SimpleObject.java, Preconditions.java


Viewing all articles
Browse latest Browse all 10

Trending Articles