Zurück zu Dbs2.
In dieser Übung werden Sie eine objektorientierte Datenbank kennenlernen. Wir verwenden das Open Source OODBS db4o (database for objects). db4o ist eine Objektdatenbank für die Java- und .NET-Plattform. Eine der wichtigsten Vorteile von db4o ist, dass Objekte gespeichert werden können, ohne dass dafür besondere Vorkehrungen getroffen werden müssen. Es ist weder notwendig, die zu speichernden Klassen von speziellen Oberklassen abzuleiten, noch müssen spezielle Interfaces implementiert werden. Auch eine Anreicherung mit Annotations ist nicht nötig. Die Objekte können dabei beliebige Typen enthalten und zudem beliebig tief verschachtelt sein.
Am häufigsten wird db4o im Embedded-Modus verwendet, d.h. die Datenbank läuft innerhalb desselben Prozesses wie die Applikation. Grundsätzlich kann db4o aber auch in einem Client/Server-Modus betrieben werden. In dieser Übung wird jedoch der Embedded-Modus benutzt.
Sie finden in diesem Paket zudem die komplette Dokumentation:
Der Object Manager Enterprise (OME) ist ein praktisches Browser- und Query-Tool für db4o-Datenbanken, das als Eclipse-Plugin installiert wird. Die Installationsanleitung befindet sich in ome/readme.html. OME wird in dieser Übung aber nicht benötigt.
In der ersten Aufgabe wird zuerst das folgende, einfache Schema verwendet:
Objekte benötigen bei db4o keine IDs. db4o verwaltet innerhalb eines ObjectContainers interne IDs, sehen Sie sich gegebenenfalls das Kapitel IDs im Tutorial an. Properties, die lediglich der eindeutigen Identifikation dienen, können folglich beim Klassenentwurf weggelassen werden.
Folgendermassen können Sie nach einem bestimmten Objekt suchen. Dies wird Query by Example genannt. Gesucht wird also mit dem Beispiel eines Objekts (nur Werte unterschiedlich von null und 0 werden für die Suche benutzt).
ObjectSet result = db.queryByExample(new Angestellter(2, null, 0)); Angestellter found = result.next();
Folgendermassen können Sie sich alle Objekte einer Klasse ausgeben lassen.
ObjectSet<Angestellter> result = db.query(Angestellter.class);
for (Angestellter each : result) {
System.out.println(each);
}
db4o arbeitet immer in einer Transaktion. Nachdem Sie die Datenbank geöffnet haben, wird also innerhalb einer Transaktion gearbeitet. Mit ObjectContainer.commit() kann die Transaktion explizit beendet werden. Danach wird unmittelbar wieder eine neue Transaktion geöffnet.
In dieser Aufgabe wird das Schema leicht erweitert:
Erstellen Sie folgende Abfragen:
Erstellen Sie folgende Abfragen:
Erstellen Sie folgende Abfragen:
Sie können sich folgendermassen ausgeben lassen, ob eine native Query optimiert wurde. db enspricht dabei Ihrem ObjectContainer.
((ObjectContainerBase) db).getNativeQueryHandler().addListener(
new Db4oQueryExecutionListener() {
public void notifyQueryExecuted(NQOptimizationInfo info) {
System.err.println(info);
}
});
db4o kennt keine Constraints (mit Ausnahme von unique). Sie können aber gewisse Dinge mit Callbacks überprüfen und darin z.B. das Löschen eines Objekts verhindern. Dazu kann ein Objekt die Methoden des Interfaces com.db4o.ext.ObjectCallbacks implementieren. Das Interface muss nicht implementiert werden, nur die Signaturen müssen übereinstimmen, die Methoden werden per Reflection auf Existenz geprüft und gegebenenfalls aufgerufen.
Einem Property einer Klasse können Sie einen Index hinzufügen. Dies muss vor dem Öffnen des ObjectContainers geschehen. Alternativ kann auch das Property direkt in der Klasse mit com.db4o.config.annotations.Indexed annotiert werden.
Db4o.configure().objectClass(Klasse.class).objectField("property").indexed(true);
angestellter.getAdresse().setStrasse("Neuestrasse");
db.store(angestellter);
db.close(); config = Db4oEmbedded.newConfiguration(); db = Db4oEmbedded.openFile(config, DB4OFILENAME);
In dieser Aufgabe wird das Schema erneut leicht erweitert:
db.close(); config = Db4oEmbedded.newConfiguration(); db = Db4oEmbedded.openFile(config, DB4OFILENAME);