Tuesday, July 04, 2006

Db4oUtil (aka. The Easiest Way to Get Started With Db4o)

Want the quickest and easiest way to get started with db4o? Use the following Db4oUtil class. This class is very similar to the HibernateUtil class that you may be familiar with if you're a Hibernate user. It uses a thread local object so it's thread safe, makes multi-tier usage a no brainer and it's just plain simple to use.

The simple step-by-step for this tutorial:

  1. Copy the Db4oUtil.java code below into a new class
  2. Use the Db4oUtil methods in your code, samples below

That is it... seriously. You can optionally tweak the fields in Db4oUtil to your liking, like you'll want to change the YAPFILENAME field for each application you will use this with.

Db4oUtil.java

public class Db4oUtil {
// EDIT THESE SETTINGS
private static final String YAPFILENAME = "test.db4o.yap";
private static final int PORT = 0;
/*
If you want the server to be networked, change the port number above and uncomment the USER, PASSWORD lines below/
Then in getObjectServer, uncomment the objectServer.grantAccess line
*/
//private static final String USER = "username";
//private static final String PASSWORD = "password";

private static ObjectServer objectServer;

private static final ThreadLocal dbThreadLocal = new ThreadLocal();

public static ObjectContainer getObjectContainer() {
ObjectContainer oc = (ObjectContainer) dbThreadLocal.get();
if (oc == null || oc.ext().isClosed()) {
oc = getObjectServer().openClient();
dbThreadLocal.set(oc);
}
return oc;
}

public static void closeObjectContainer() {
ObjectContainer oc = (ObjectContainer) dbThreadLocal.get();
dbThreadLocal.set(null);
if (oc != null) oc.close();
}

public synchronized static ObjectServer getObjectServer() {
if (objectServer == null) {
objectServer = getObjectServerForFilename(YAPFILENAME, PORT);
// and give access
//objectServer.grantAccess(USER, PASSWORD);
}
return objectServer;
}


public static void shutdown() {
if (objectServer != null) {
objectServer.close();
}
}

public static ObjectServer getObjectServerForFilename(String yapfilename, int port) {
File parentDir = getDbDirectory();
File dbfile = new File(parentDir, yapfilename);

// for replication //////////////////////////
Db4o.configure().generateUUIDs(Integer.MAX_VALUE);
Db4o.configure().generateVersionNumbers(Integer.MAX_VALUE);

// other options
Db4o.configure().exceptionsOnNotStorable(true);
Db4o.configure().objectClass("java.math.BigDecimal").translate(new com.db4o.config.TSerializable());

// now open server
ObjectServer objectServer = Db4o.openServer(dbfile.getPath(), port);

return objectServer;
}

private static File getDbDirectory() {
// will store data files in {user.home}/db4o/data directory
String dbfile = System.getProperty("user.home") + "/db4o/data";
File f = new File(dbfile);
if (!f.exists()) {
f.mkdirs();
}
return f;
}
}
You can edit the fields at the top to modify your database filename, etc.

Using Db4oUtil

This is a simple code sample of usage:
// Get ObjectContainer - you can repetitively call this function in different methods without the need to pass the ObjectContainer around
ObjectContainer oc = Db4oUtil.getObjectContainer();

// YOUR CODE HERE - use the ObjectContainer and do all your stuff here

// Close ObjectContainer when done
Db4oUtil.closeDb();

// Close object server when completely exiting application
Db4oUtil.shutdown();
That's all there is to it!