Handbuch zu Java-Datenobjekten

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.