1. 概要

Java Data Objectsは、オブジェクト指向データを任意のデータベースに永続化するために設計されたAPIであり、Java構文を使用してユーザーフレンドリーなクエリ言語を提供します。

この記事では、JDOAPIを使用してオブジェクトをデータベースに永続化する方法を説明します。

2. Mavenの依存関係とセットアップ

最新のDataNucleusJDOAPIを使用し、JDO3.2APIを完全にサポートします。

pom.xmlファイルに次の依存関係を追加しましょう。

<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>javax.jdo</artifactId>
    <version>3.2.0-m6</version>
</dependency>
<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-core</artifactId>
    <version>5.1.0-m2</version>
</dependency>
<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-api-jdo</artifactId>
    <version>5.1.0-m2</version>
</dependency>
<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-rdbms</artifactId>
    <version>5.1.0-m2</version>
</dependency>
<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-xml</artifactId>
    <version>5.0.0-release</version>
</dependency>        

依存関係の最新バージョンは、 javax.jdo datanucleus-core datanucleus-api-jdo datanucleus-rdbms[ X157X]および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ビルド中にこれを自動的に行うことは可能です。

<plugin>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-maven-plugin</artifactId>
    <version>5.0.2</version>
    <configuration>
        <api>JDO</api>
        <props>${basedir}/datanucleus.properties</props>
        <log4jConfiguration>${basedir}/log4j.properties</log4jConfiguration>
        <verbose>true</verbose>
    </configuration>
    <executions>
        <execution>
            <phase>process-classes</phase>
            <goals>
                <goal>enhance</goal>
            </goals>
        </execution>
    </executions>
</plugin>

プラグインの最新バージョンはここにあります: 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);

finally ブロックでは、障害が発生した場合に実行されるこれらの操作を定義します。

何らかの理由でトランザクションを完了できない場合は、ロールバックを実行し、 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<Product> products = (List<Product>) q.execute();
Iterator<Product> 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ファイルを使用できます。

XMLファイルであることを示すConnectionURLを指定し、ファイルの名前を指定します:

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

XMLデータストアはauto-incrementプロパティをサポートしていないため、別のクラスを作成する必要があります。

@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ファイルに保存します。

<productXML productNumber="0">
    <name>Tablet</name>
    <price>80.0</price>
</productXML>

8.1. XMLデータストアからオブジェクトを回復する

クエリを使用して、XMLファイルからオブジェクトを回復できます。

Query q = pm.newQuery("SELECT FROM " + ProductXML.class.getName());
List<ProductXML> products = (List<ProductXML>) 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");
List<Product> resultsqDJDOQL = 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);
List<Product> results = query.executeList();

javax.jdo.query.SQL をクエリオブジェクトの1つのパラメーターとして使用し、2番目のパラメーターは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. 概要

このチュートリアルでは、次のことを行います。

  • JDOを使用する単純なCRUDアプリケーションを作成しました
  • データをXMLとして保存および取得しました
  • 一般的なクエリメカニズムを調べた

いつものように、Githubの記事からコードを見つけることができます。