DB4O
Tuesday, 15. February 2011
Db4o ist eine freie Datenbank für Objekte. In meiner Datenbankvorlesung habe ich noch gelernt, dass sowas zwar faszinierend, aber esoterischer Quatsch ist, der in der Praxis aus diversen Gründen nicht funktioniert. Es mag auch durchaus sein, dass es Gründe gibt, db4o nicht einzusetzen - bei meinem (natürlich vergleichsweise kleinem) Projekt konnte ich keine finden.
Speichern
Nochmal: db4o ist eine Datenbank für Objekte. Man speichert ein Objekt hinein und bekommt zu einem beliebigen späteren Zeitpunkt genau das gleiche Objekt zurück. Das Speichern ist simpel:
Cpu cpu = new Cpu(); ObjectContainer cpuDB = Db4o.openFile("cpus");; cpuDB.store(cpu);
Hier wurde eine Datei als Datenbank verwendet, "cpus", und dort hinein das neuerstelle Objekt gespeichert.
Select
Aber Speichern hilft nicht, wenn es nicht einfache Wege gibt, wieder das Objekt zu holen. db4o kennt zwei, und der erste ist wirklich simpel: queryByExample. Man erstellt ein Objekt, bei dem das Suchattribut gesetzt ist, alles andere steht auf default und wird ignoriert. Dann übergibt man das der Datenbank und bekommt all die Objekte mit dem gleichen Attribut zurück. Ein Beispiel:
Cpu exampleCpu = new Cpu(); exampleCpu.setSocket("A"); ObjectContainer cpuDB = Db4o.openFile("cpus"); ObjectSet<Cpu> cpuResult = cpuDB.queryByExample(exampleCpu); // ==>Nur Cpus mit Sockel A
Und ein Select *, also alle Cpus? Das geht über die Klasse:
ObjectSet<Cpu> cpuResult = cpuDB.queryByExample(Cpu.class);
Alternativ gibt es noch die native queries. Bei ihnen läuft ein Matcher über die Datenbank:
// Nur Cpus günstiger als 200: List<Cpu> result = container.query(new Predicate<Cpu>() { public boolean match(Cpu cpu) { return cpu.price < 200; } });
Editieren
Eine Objektdatenbank, oder zumindest db4o, hat eine andere Definition von Identität als eine SQL-Datenbank. Es wird nicht einfach ein unique key auf id gesetzt und dann verhindert die Datenbank, dass so etwas nochmal eingesetzt wird, und wird bei db4o ein Objekt gespeichert, das die gleichen Attribute wie ein anderes hat, ist ein solches Objekt eben zweimal vorhanden. Trotzdem kann man ein Objekt holen, editieren und mit den Änderungen speichern, ohne dass es Duplikate gibt:
private void updatePrice(Cpu cpu, double price, ObjectContainer cpuDB) { ObjectSet<Cpu> found = cpuDB.queryByExample(cpu); cpu = found.get(0); cpu.price = price; cpuDB.store(cpu); }
Löschen folgt dem gleichen Prinzip:
public void delete(Cpu cpu) { ObjectContainer cpuDB = Db4o.openFile(path+"cpus"); ObjectSet found = cpuDB.queryByExample(cpu); cpuDB.delete(found.get(0)); cpuDB.close(); }
Fazit
Db4o hat mich ziemlich begeistert. Ich musste einige Objekte speichern und wieder holen, und mir war klar, dass sich die Struktur dieser Objekte im Laufe der Entwicklung noch häufig ändern wird. Jedesmal ein SQL-Schema abzuändern oder neu zu erstellen wäre grausam gewesen. Überhaupt ein SQL-Schema zu erstellen wäre grausam gewesen. So brauchte ich mich darum nicht kümmern: Objekt gespeichert, Objekt geholt. Änderte sich mal was an den Objekten, wurde die alte Datenbank eben gelöscht, erstellt sich ja von selbst neu.
Ich kann die Performance nicht bewerten - es ist möglich, dass db4o bei großen Datenmengen gegen eine SQL-Datenbank verliert. Ich kann nicht sagen, ob es ansonsten gewichtige Gründe gibt, diese Objektdatenbank zu meiden, ich spare mir hier das Aufzählen der theoretischen Gegenargumente. Aber ich kann sagen: Bei mir hat db4o wunderbar funktioniert und die Entwicklung erheblich vereinfacht. Wenn ich nochmal Daten speichern will, die als Objekt bereits vorliegen und so wieder gebraucht werden, würde ich es nochmal hiermit versuchen.