Ръководство за Java Data Objects

1. Общ преглед

Java Data Objects е API, предназначен за персистиране на обектно-ориентирани данни във всяка база данни и предоставя лесен за потребител език за заявки, използвайки синтаксиса на Java.

В тази статия ще видим как да използваме JDO API за персистиране на нашите обекти в база данни.

2. Зависимости и настройка на Maven

Ще използваме DataNucleus JDO API, който е актуален и предлага пълна поддръжка за JDO 3.2 API.

Нека добавим следната зависимост към нашия файл 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  

Най-новите версии на зависимостите можете да намерите тук: javax.jdo, datanucleus-core, datanucleus-api-jdo, datanucleus-rdbms и datanucleus-xml.

3. Модел

Ще запишем данните си в база данни и преди да можем да го направим, трябва да създадем клас, който да се използва от JDO за съхранение на данните ни.

За целта трябва да създадем клас с някои свойства и да го анотираме с @PersistentCapable:

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

Също така коментирахме нашия първичен ключ и избраната стратегия.

След като създадем обекта си, трябва да стартираме подобрителя, за да генерираме байт кода, изискван от JDO. Използвайки Maven, можем да изпълним тази команда:

mvn datanucleus:enhance

Тази стъпка е задължителна. В противен случай получаваме грешка във времето на компилация, че класът не е подобрен.

Разбира се, възможно е да направите това автоматично по време на компилация на Maven:

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

Най-новата версия на приставката можете да намерите тук: datanucleus-maven-plugin

4. Персистиращи предмети

Получаваме достъп до базата данни, използвайки фабрика JDO, която ни дава мениджър на транзакции, който отговаря за извършването на транзакции:

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

Транзакциите се използват, за да позволят връщане в случай на грешка:

Transaction tx = pm.currentTransaction();

Правим транзакциите си в блок try / catch :

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

В нашия окончателен блок ние дефинираме тези операции да се извършват в случай на повреда.

Ако по някаква причина транзакцията не може да бъде завършена, правим връщане назад и също така затваряме връзката с базата данни с pm.close () :

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

За да свържем нашата програма с базата данни, трябва да създадем постоянна единица по време на изпълнение, за да посочим постоянните класове, типа на базата данни и параметрите на свързване:

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. Четене на обекти

За да четем данни от нашата база данни в нашия транзакционен блок, ние създаваме заявка. След това съхраняваме тези елементи в колекция от Java List , която ще съхранява копие в паметта на информацията от постоянното хранилище.

Мениджърът на постоянството ни дава достъп до интерфейса на заявката, който ни позволява да взаимодействаме с базата данни:

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. Актуализиране на обекти

За да актуализираме обекти в базата данни, трябва да намерим обектите, които искаме да актуализираме с помощта на заявка, след това актуализираме резултатите от заявката и ангажираме транзакцията:

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

7. Изтриване на обекти

Подобно на процедурата за актуализация, първо търсим обекта и след това го изтриваме с помощта на мениджъра за постоянство. В тези ситуации JDO актуализира постоянното хранилище:

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 хранилища за данни

Използвайки приставката XML, можем да използваме XML файлове за запазване на нашите данни.

Ние посочваме нашия ConnectionURL, посочвайки, че е XML файл и посочвайки името на файла:

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

Хранилището на XML данни не поддържа свойството за автоматично увеличаване, така че трябва да създадем друг клас:

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