Chris Umbel

Object Oriented Databases with db4o

One of the most notable initiatives in the business software development industry in the last few years is the simplification of data access. The core complication lies in the impedance mismatch between relational storage and object oriented code higher in the stack. Far too much plumbing is required to map object properties to columns in result sets, deal with data type variations and handle other annoyances.

The most popular response to the problem has been to leave relational storage in place and introduce ORM (Object Relational Mapping) frameworks to automate the conversion between relational and object oriented structures. This approach is popular in business environments because having a relational database under the hood offers many advantages such as ease of reporting and integration.

Object oriented databases, however, offer an interesting alternative.

While I personally think it'll be quite some time before object oriented databases are reasonable for most large-scale enterprise applications they're certainly viable for a range of projects and can be incredibly simple to adopt.

As a demonstration I'll whip up a quick .Net console app that will employ db4o, a popular object oriented database product, to store and query some simple sales order data.

First we need some objects to store. I'll define the following "Order" and "Detail" classes for my application to consume, store and query. Nothing special has to be done to these classes to make them eligible for db40 persistence. This will all be purely POCO.

public class Detail
{
	public int ItemNumber { get; set; }
	public short Qty { get; set; }
}

public class Order
{
	public string CustomerName { get; set; }
	public List<Detail> Details = new List<Detail>();
}

Now I'll set up a connection to a database file. Note that it's also possible for db4o to operate against a server over a network.

IObjectContainer database = Db4oFactory.OpenFile("test.db4o");

Keep in mind that the file "test.db4o" does not have to exist on the filesystem before our code is run. If the file does not exist db4o will create it for us.

Now I'll instantiate some Order and Detail objects and persist them to disk via "Db4oFactory"'s "Store" method.

database.Store(new Order() { CustomerName = "Chris Umbel", 
	Details = new List<Detail>() { 
		new Detail() { ItemNumber = 1, Qty = 3} 
	} 
});

database.Store(new Order() { CustomerName = "Billiam Smith", 
	Details = new List<Detail>() { 
		new Detail() { ItemNumber = 1, Qty = 1 }, 
		new Detail() { ItemNumber = 2, Qty = 1} 
	} 
});

That was pretty easy and about as plumbing free as could be hoped for. Now I'll use Linq to query what we've stored.

IEnumerable<Order> orders = 
	from Order o in database 
	from Detail d in o.Details
	where d.ItemNumber == 2
	select o;

foreach (Order o in orders)
{
	Console.WriteLine(o.CustomerName);
}

Which produces the following output:

Billiam Smith

because that was the only order stored containing an item #2.

db40 also offers other methods of querying than Linq such as their "Native Query" implementation, Query-By-Example and the SODA API, but they're beyond the scope of this introduction.

As a final matter of housekeeping I'll clean up after myself and close my connection to the database file.

database.Close();

Based on that simple example it's evident that persisting objects with db4o is painless and requires minimal plumbing to implement. More importantly still it does not impose any restrictions on the inheritance chain so you can subclass however you chose.

There are plenty of other object oriented database systems out there each with their own strengths and weaknesses. I recommend checking out ODBMS.org for more info on the subject.

Sun Jun 07 2009 18:37:34 GMT+0000 (UTC)

Follow Chris
RSS Feed
Twitter
Facebook
CodePlex
github
LinkedIn
Google