Guida agli oggetti dati Java

1. Panoramica

Java Data Objects è un'API progettata per la persistenza dei dati orientati agli oggetti in qualsiasi database e fornisce un linguaggio di query intuitivo utilizzando la sintassi Java.

In questo articolo, vedremo come utilizzare l'API JDO per rendere persistenti i nostri oggetti in un database.

2. Dipendenze e installazione di Maven

Utilizzeremo l'API JDO DataNucleus che è aggiornata e offre pieno supporto per l'API JDO 3.2.

Aggiungiamo la seguente dipendenza al nostro file pom.xml :

 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  

Le ultime versioni delle dipendenze possono essere trovate qui: javax.jdo, datanucleus-core, datanucleus-api-jdo, datanucleus-rdbms e datanucleus-xml.

3. Modello

Salveremo i nostri dati in un database e prima di poterlo fare, dobbiamo creare una classe che verrà utilizzata da JDO per memorizzare i nostri dati.

Per fare ciò dobbiamo creare una classe con alcune proprietà e annotarla con @PersistentCapable:

@PersistenceCapable public class Product { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.INCREMENT) long id; String name; Double price = 0.0; // standard constructors, getters, setters }

Abbiamo anche annotato la nostra chiave primaria e la strategia scelta.

Una volta creato il nostro oggetto, dobbiamo eseguire il potenziatore per generare il bytecode richiesto da JDO. Usando Maven, possiamo eseguire questo comando:

mvn datanucleus:enhance

Questo passaggio è obbligatorio. Altrimenti, otteniamo un errore in fase di compilazione che la classe non è migliorata.

Ovviamente è possibile farlo automaticamente durante una build di Maven:

 org.datanucleus datanucleus-maven-plugin 5.0.2  JDO ${basedir}/datanucleus.properties ${basedir}/log4j.properties true    process-classes  enhance    

L'ultima versione del plugin può essere trovata qui: datanucleus-maven-plugin

4. Oggetti persistenti

Otteniamo l'accesso al database utilizzando una fabbrica JDO che ci fornisce il gestore delle transazioni incaricato di eseguire le transazioni:

PersistenceManagerFactory pmf = new JDOPersistenceManagerFactory(pumd, null); PersistenceManager pm = pmf.getPersistenceManager(); 

Le transazioni vengono utilizzate per consentire un rollback in caso di errore:

Transaction tx = pm.currentTransaction();

Effettuiamo le nostre transazioni all'interno di un blocco try / catch :

Product product = new Product("Tablet", 80.0); pm.makePersistent(product);

Nel nostro finalmente blocco, definiamo queste operazioni da fare nel caso di un fallimento.

Se per qualsiasi motivo la transazione non può essere completata, effettuiamo un rollback e chiudiamo anche la connessione al database con pm.close () :

finally { if (tx.isActive()) { tx.rollback(); } pm.close(); }

Per connettere il nostro programma al database, dobbiamo creare un'unità di persistenza in fase di esecuzione per specificare le classi persistenti, il tipo di database e i parametri di connessione:

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. Lettura di oggetti

Per leggere i dati dal nostro database all'interno del nostro blocco di transazioni, creiamo una query. Quindi, archiviamo questi elementi in una raccolta di elenchi Java , che conterrà una copia in memoria delle informazioni dalla memoria persistente.

Il persistence manager ci dà un accesso all'interfaccia di query che ci permette di interagire con il database:

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. Aggiornamento di oggetti

Per aggiornare gli oggetti nel database dobbiamo trovare gli oggetti che vogliamo aggiornare utilizzando una query, quindi aggiorniamo i risultati della query e commettere la transazione:

Query query = pm.newQuery(Product.class, "name == \"Phone\""); Collection result = (Collection) query.execute(); Product product = (Product) result.iterator().next(); product.setName("Android Phone"); 

7. Eliminazione di oggetti

Analogamente alla procedura di aggiornamento, cerchiamo prima l'oggetto e poi lo cancelliamo utilizzando il gestore di persistenza. In queste situazioni, JDO aggiorna la memoria persistente:

Query query = pm.newQuery(Product.class, "name == \"Android Phone\""); Collection result = (Collection) query.execute(); Product product = (Product) result.iterator().next(); pm.deletePersistent(product); 

8. Datastore XML

Usando il plugin XML, possiamo usare file XML per conservare i nostri dati.

Specifichiamo il nostro ConnectionURL indicando che è un file XML e specificando il nome del file:

pumdXML.addProperty("javax.jdo.option.ConnectionURL", "xml:file:myPersistence.xml");

Un datastore XML non supporta la proprietà di incremento automatico, quindi è necessario creare un'altra classe:

@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.