1. Обзор
Объекты данных Java – это API, предназначенный для сохранения объектно-ориентированных данных в любой базе данных и предоставляющий удобный язык запросов с использованием синтаксиса Java.
В этой статье мы рассмотрим, как использовать API JDO для сохранения ваших объектов в базе данных.
2. Зависимости и настройка Maven
Мы собираемся использовать DataNucleus JDO API, который является современным и предлагает полную поддержку API JDO 3.2.
Давайте добавим следующую зависимость к вашему 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 для хранения наших данных.
Для этого нам нужно создать класс с некоторыми свойствами и аннотировать его с помощью @Persistencecapable:
@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. Сохраняющиеся Объекты
Мы получаем доступ к базе данных с помощью JDOfactory, который предоставляет нам менеджер транзакций, отвечающий за выполнение транзакций:
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);
В нашем блоке finally мы определяем эти операции, которые будут выполняться в случае сбоя.
Если по какой-либо причине транзакция не может быть завершена, мы выполняем откат, а также закрываем соединение с базой данных с помощью pm.close() :
finally { if (tx.isActive()) { tx.rollback(); } pm.close(); }
Чтобы подключить нашу программу к базе данных, нам нужно создать persistence-unit во время выполнения, чтобы указать постоянные классы, тип базы данных и параметры подключения:
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"); Listproducts = (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. Удаление Объектов
Аналогично процедуре обновления, мы сначала ищем объект, а затем удаляем его с помощью persistencemanager. В таких ситуациях 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-файлы для сохранения наших данных.
Мы указываем наш URL-адрес подключения , указывая, что это XML-файл, и указывая имя файла:
pumdXML.addProperty("javax.jdo.option.ConnectionURL", "xml:file:myPersistence.xml");
Хранилище данных XML не поддерживает свойство autoincrement, поэтому нам нужно создать другой класс:
@PersistenceCapable() public class ProductXML { @XmlAttribute private long productNumber = 0; @PrimaryKey private String name = null; private Double price = 0.0; // standard getters and setters
Аннотация @XmlAttribute указывает, что это будет отображаться в XML-файле в качестве атрибута элемента.
Давайте создадим и сохраним наш продукт:
ProductXML productXML = new ProductXML(0,"Tablet", 80.0); pm.makePersistent(productXML);
Мы получаем продукт, хранящийся в XML – файле:
Tablet 80.0
8.1. Восстановление объектов из хранилища XML-данных
Мы можем восстановить наши объекты из XML-файла с помощью запроса:
Query q = pm.newQuery("SELECT FROM " + ProductXML.class.getName()); Listproducts = (List ) q.execute();
А затем мы используем итератор для взаимодействия с каждым объектом.
9. Запросы JDO
JDOQL-это объектно-ориентированный язык запросов, предназначенный для выполнения запросов с использованием объектов Java.
9.1. Декларативный JDOQL
Используя декларативный запрос, мы объявляем параметры и устанавливаем их с помощью Java, это обеспечивает безопасность типов:
Query qDJDOQL = pm.newQuery(Product.class); qDJDOQL.setFilter("name == 'Tablet' && price == price_value"); qDJDOQL.declareParameters("double price_value"); ListresultsqDJDOQL = qDJDOQL.setParameters(80.0).executeList();
9.2. SQL
JDO предоставляет механизм для выполнения стандартных запросов SQL:
Query query = pm.newQuery("javax.jdo.query.SQL", "SELECT * FROM PRODUCT"); query.setClass(Product.class); Listresults = query.executeList();
Мы используем javax.jdo.query.SQL в качестве одного параметра для объекта запроса, а вторым параметром является сам SQL.
9.3. JPQL
JDO также предоставляет механизм для выполнения запросов JPA. Мы можем использовать полный синтаксис языка запросов JPA:
Query q = pm.newQuery("JPQL", "SELECT p FROM " + Product.class.getName() + " p WHERE p.name = 'Laptop'"); List results = (List) q.execute();
10. Резюме
В этом уроке мы:
- создал простое приложение CRUD, которое использует JDO
- сохраненные и извлеченные наши данные в формате XML
- рассмотрены общие механизмы запросов
Как всегда, вы можете найти код из статьи на Github .