1. Übersicht
Die Java-Datenobjekte sind eine API, mit der objektorientierte Daten in einer beliebigen Datenbank gespeichert und mithilfe der Java-Syntax eine benutzerfreundliche Abfragesprache bereitgestellt werden können.
In diesem Artikel erfahren Sie, wie Sie die JDO-API zum Speichern unserer Objekte in einer Datenbank verwenden.
2. Maven-Abhängigkeiten und Setup
Wir werden die aktuelle DataNucleus JDO-API verwenden, die die JDO 3.2-API vollständig unterstützt.
Fügen wir unserer Datei pom.xml die folgende Abhängigkeit hinzu :
org.datanucleus javax.jdo 3.2.0-m6 org.datanucleus datanucleus-core 5.1.0-m2 org.datanucleus datanucleus-api-jdo 5.1.0-m2 org.datanucleus datanucleus-rdbms 5.1.0-m2 org.datanucleus datanucleus-xml 5.0.0-release
Die neuesten Versionen der Abhängigkeiten finden Sie hier: javax.jdo, datanucleus-core, datanucleus-api-jdo, datanucleus-rdbms und datanucleus-xml.
3. Modell
Wir werden unsere Daten in einer Datenbank speichern, und bevor wir dies tun können, müssen wir eine Klasse erstellen, die von JDO zum Speichern unserer Daten verwendet wird.
Dazu müssen wir eine Klasse mit einigen Eigenschaften erstellen und mit @PersistentCapable kommentieren :
@PersistenceCapable public class Product { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.INCREMENT) long id; String name; Double price = 0.0; // standard constructors, getters, setters }
Wir haben auch unseren Primärschlüssel und die gewählte Strategie kommentiert.
Sobald wir unser Objekt erstellt haben, müssen wir den Enhancer ausführen, um den für JDO erforderlichen Bytecode zu generieren. Mit Maven können wir diesen Befehl ausführen:
mvn datanucleus:enhance
Dieser Schritt ist obligatorisch. Andernfalls wird der Fehler bei der Kompilierung angezeigt, dass die Klasse nicht erweitert wurde.
Natürlich ist dies während eines Maven-Builds automatisch möglich:
org.datanucleus datanucleus-maven-plugin 5.0.2 JDO ${basedir}/datanucleus.properties ${basedir}/log4j.properties true process-classes enhance
Die neueste Version des Plugins finden Sie hier: datanucleus-maven-plugin
4. Persistierende Objekte
Wir erhalten Zugriff auf die Datenbank über eine JDO-Factory, die uns den Transaktionsmanager gibt, der für die Ausführung von Transaktionen verantwortlich ist:
PersistenceManagerFactory pmf = new JDOPersistenceManagerFactory(pumd, null); PersistenceManager pm = pmf.getPersistenceManager();
Transaktionen werden verwendet, um im Fehlerfall ein Rollback zu ermöglichen:
Transaction tx = pm.currentTransaction();
Wir machen unsere Transaktionen innerhalb eines Try / Catch- Blocks:
Product product = new Product("Tablet", 80.0); pm.makePersistent(product);
In unserem letzten Block definieren wir diese Operationen, die im Falle eines Fehlers ausgeführt werden sollen.
Wenn die Transaktion aus irgendeinem Grund nicht abgeschlossen werden kann, führen wir einen Rollback durch und schließen die Verbindung zur Datenbank mit pm.close () :
finally { if (tx.isActive()) { tx.rollback(); } pm.close(); }
Um unser Programm mit der Datenbank zu verbinden, müssen wir zur Laufzeit eine Persistenz-Einheit erstellen , um die persistenten Klassen, den Datenbanktyp und die Verbindungsparameter anzugeben:
PersistenceUnitMetaData pumd = new PersistenceUnitMetaData( "dynamic-unit", "RESOURCE_LOCAL", null); pumd.addClassName("com.baeldung.jdo.Product"); pumd.setExcludeUnlistedClasses(); pumd.addProperty("javax.jdo.option.ConnectionDriverName", "org.h2.Driver"); pumd .addProperty("javax.jdo.option.ConnectionURL", "jdbc:h2:mem:mypersistence"); pumd.addProperty("javax.jdo.option.ConnectionUserName", "sa"); pumd.addProperty("javax.jdo.option.ConnectionPassword", ""); pumd.addProperty("datanucleus.autoCreateSchema", "true");
5. Objekte lesen
Um Daten aus unserer Datenbank in unserem Transaktionsblock zu lesen, erstellen wir eine Abfrage. Anschließend speichern wir diese Elemente in einer Java List- Sammlung, die eine speicherinterne Kopie der Informationen aus dem persistenten Speicher enthält.
Der Persistenzmanager gibt uns Zugriff auf die Abfrageoberfläche, über die wir mit der Datenbank interagieren können:
Query q = pm.newQuery( "SELECT FROM " + Product.class.getName() + " WHERE price < 1"); List products = (List) q.execute(); Iterator iter = products.iterator(); while (iter.hasNext()) { Product p = iter.next(); // show the product information }
6. Objekte aktualisieren
Um Objekte in der Datenbank zu aktualisieren, müssen wir die Objekte finden, die wir mithilfe einer Abfrage aktualisieren möchten. Anschließend aktualisieren wir die Ergebnisse der Abfrage und schreiben die Transaktion fest:
Query query = pm.newQuery(Product.class, "name == \"Phone\""); Collection result = (Collection) query.execute(); Product product = (Product) result.iterator().next(); product.setName("Android Phone");
7. Objekte löschen
Ähnlich wie beim Aktualisierungsvorgang suchen wir zuerst nach dem Objekt und löschen es dann mit dem Persistenzmanager. In diesen Situationen aktualisiert JDO den persistenten Speicher:
Query query = pm.newQuery(Product.class, "name == \"Android Phone\""); Collection result = (Collection) query.execute(); Product product = (Product) result.iterator().next(); pm.deletePersistent(product);
8. XML-Datenspeicher
Mit dem XML-Plugin können wir XML-Dateien verwenden, um unsere Daten zu speichern.
Wir geben unsere ConnectionURL an, die angibt, dass es sich um eine XML-Datei handelt, und geben den Namen der Datei an:
pumdXML.addProperty("javax.jdo.option.ConnectionURL", "xml:file:myPersistence.xml");
Ein XML-Datenspeicher unterstützt die Auto-Inkrement-Eigenschaft nicht. Daher müssen wir eine weitere Klasse erstellen:
@PersistenceCapable() public class ProductXML { @XmlAttribute private long productNumber = 0; @PrimaryKey private String name = null; private Double price = 0.0; // standard getters and setters
The @XmlAttribute annotation denotes that this will appear in the XML file as an attribute of the element.
Let's create and persist our product:
ProductXML productXML = new ProductXML(0,"Tablet", 80.0); pm.makePersistent(productXML);
We get the product stored in the XML file:
Tablet 80.0
8.1. Recover Objects from the XML Datastore
We can recover our objects from the XML file using a query:
Query q = pm.newQuery("SELECT FROM " + ProductXML.class.getName()); List products = (List) q.execute();
And then we use the iterator to interact with each object.
9. JDO Queries
JDOQL is an object-based query language designed to perform queries using Java objects.
9.1. Declarative JDOQL
Using the declarative query, we declare the parameters and set them using Java, this ensures type safety:
Query qDJDOQL = pm.newQuery(Product.class); qDJDOQL.setFilter("name == 'Tablet' && price == price_value"); qDJDOQL.declareParameters("double price_value"); List resultsqDJDOQL = qDJDOQL.setParameters(80.0).executeList();
9.2. SQL
JDO provides a mechanism for executing standard SQL queries:
Query query = pm.newQuery("javax.jdo.query.SQL", "SELECT * FROM PRODUCT"); query.setClass(Product.class); List results = query.executeList();
We use javax.jdo.query.SQL as one parameter for the query object and the second parameter is the SQL itself.
9.3. JPQL
JDO provides a mechanism for executing JPA queries as well. We can use the full syntax of the JPA query language:
Query q = pm.newQuery("JPQL", "SELECT p FROM " + Product.class.getName() + " p WHERE p.name = 'Laptop'"); List results = (List) q.execute();
10. Summary
In this tutorial, we:
- created a simple CRUD application that uses JDO
- saved and retrieved our data as XML
- examined common query mechanisms
As always, you can find the code from the article over on Github.