For a custom typehandler example we will try to write a very simple typehandler for the StringBuilder class. We want to handle a StringBuilder as a value type, therefore we implement the ValueTypeHandler interface. Not that there's a whole collection of interfaces for typehandlers. Take a look at the TypeHandler4 type hierarchy.
To keep it simple we will skip information required for indexing - please look at IndexableTypeHandler in db4o sources to get more information on how to handle indexes.
The first thing should be the write method, which determines how the object is persisted:
@Override public void write(WriteContext writeContext, Object o) { StringBuilder builder = (StringBuilder) o; String str = builder.toString(); final byte[] bytes = str.getBytes(CHAR_SET); writeContext.writeInt(bytes.length); writeContext.writeBytes(bytes); }
As you can see from the code above, there are 3 steps:
Next step is to read the stored object. It is just opposite to the write method:
@Override public Object read(ReadContext readContext) { final int length = readContext.readInt(); byte[] data = new byte[length]; readContext.readBytes(data); return new StringBuilder(new String(data,CHAR_SET)); } }
Delete is simple - we just reposition the buffer offset to the end of the slot:
@Override public void delete(DeleteContext deleteContext) throws Db4oIOException { skipData(deleteContext); } private void skipData(ReadBuffer deleteContext) { int numBytes = deleteContext.readInt(); deleteContext.seek(deleteContext.offset()+ numBytes); }
The last method left: #defragment. This one only moves the offset to the beginning of the object data, i.e. skips Id and size information (to be compatible to older versions):
@Override public void defragment(DefragmentContext defragmentContext) { skipData(defragmentContext); }
Now to use this type handler we need to configure db4o. To register a typehandler you have to provide a predicate which decides if a type is handled by the typehandler and the typehandler itself.
EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration(); configuration.common().registerTypeHandler( new SingleClassTypeHandlerPredicate(StringBuilder.class), new StringBuilderHandler());
After that all string builders are handled by you're type handler.