1. 概要

このシリーズの前回の記事では、Javaオブジェクトをさまざまなデータストアに永続化する方法を示しました。 詳細については、Javaデータオブジェクトガイドを確認してください。

JDOはさまざまなクエリ言語をサポートしており、開発者が最も精通しているクエリ言語を使用できる柔軟性を提供します。

2. JDOクエリ言語

JDOは、次のクエリ言語をサポートしています。

  • JDOQL –Java構文を使用したクエリ言語
  • タイプされたJDOQL– JDOQL構文に従いますが、クエリの使用を容易にするAPIを提供します。
  • SQL –RDBMSにのみ使用されます。
  • JPQL – Datanucleusによって提供されますが、JDO仕様の一部ではありません。

3. クエリAPI

3.1. クエリの作成

クエリを作成するには、言語とクエリ String:を指定する必要があります

Query query = pm.newQuery(
  "javax.jdo.query.SQL",
  "select * from product_item where price < 10");

言語を指定しない場合、デフォルトでJDOQLになります。

Query query = pm.newQuery(
  "SELECT FROM com.baeldung.jdo.query.ProductItem WHERE price < 10");

3.2. 名前付きクエリの作成

クエリを定義して、保存された名前で参照することもできます。

そのためには、最初にProductItemクラスを作成します。

@PersistenceCapable
public class ProductItem {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.INCREMENT)
    int id;
    String name;
    String status;
    String description;
    double price;

    //standard getters, setters & constructors
}

次に、クラス構成を META-INF / package.jdo ファイルに追加して、クエリを定義し、名前を付けます。

<jdo>
    <package name="com.baeldung.jdo.query">
        <class name="ProductItem" detachable="true" table="product_item">
            <query name="PriceBelow10" language="javax.jdo.query.SQL">
            <![CDATA[SELECT * FROM PRODUCT_ITEM WHERE PRICE < 10]]>
            </query>
        </class>
    </package>
</jdo>

「」という名前のクエリを定義しました PriceBelow10″。

コードで使用できます。

Query<ProductItem> query = pm.newNamedQuery(
  ProductItem.class, "PriceBelow10");
List<ProductItem> items = query.executeList();

3.3. クエリを閉じる

リソースを節約するために、クエリを閉じることができます。

query.close();

同様に、 close()メソッドにパラメーターとして渡すことにより、特定の結果セットを閉じることができます。

query.close(ResultSet);

3.4. クエリのコンパイル

クエリを検証する場合は、 compile()メソッドを呼び出すことができます。

query.compile();

クエリが有効でない場合、メソッドはJDOException。をスローします。

4. JDOQL

JDOQLはオブジェクトベースのクエリ言語であり、SQL言語の能力を提供し、アプリケーションモデルでJavaオブジェクトの関係を維持するように設計されています。

JDOQLクエリは、単一文字列形式で定義できます。

深く掘り下げる前に、いくつかの基本的な概念を見ていきましょう。

4.1. 候補者クラス

JDOQLの候補クラスは、永続化可能なクラスである必要があります。 SQL言語では、テーブル名の代わりに完全なクラス名を使用しています。

Query query = pm.newQuery("SELECT FROM com.baeldung.jdo.query.ProductItem");
List<ProductItem> r = query.executeList();

上記の例でわかるように、com.baeldung.jdo.query.ProductItemがここでの候補クラスです。

4.2. フィルター

フィルタはJavaで記述できますが、ブール値に評価する必要があります。

Query query = pm.newQuery("SELECT FROM com.baeldung.jdo.query.ProductItem");
query.setFilter("status == 'SoldOut'");
List<ProductItem> result = query.executeList();

4.3. メソッド

JDOQLはすべてのJavaメソッドをサポートしているわけではありませんが、クエリから呼び出すことができ、幅広い範囲で使用できるさまざまなメソッドをサポートしています。

query.setFilter("this.name.startsWith('supported')");

サポートされているメソッドの詳細については、このリンクを確認してください。

4.4. パラメーター

値をパラメータとしてクエリに渡すことができます。 パラメータは明示的または暗黙的に定義できます。

パラメータを明示的に定義するには:

Query query = pm.newQuery(
  "SELECT FROM com.baeldung.jdo.query.ProductItem "
  + "WHERE price < threshold PARAMETERS double threshold");
List<ProductItem> result = (List<ProductItem>) query.execute(10);

これは、setParametersメソッドを使用して実現することもできます。

Query query = pm.newQuery(
  "SELECT FROM com.baeldung.jdo.query.ProductItem "
  + "WHERE price < :threshold");
query.setParameters("double threshold");
List<ProductItem> result = (List<ProductItem>) query.execute(10);

パラメータタイプを定義しないことで、暗黙的にそれを行うことができます。

Query query = pm.newQuery(
  "SELECT FROM com.baeldung.jdo.query.ProductItem "
  + "WHERE price < :threshold");
List<ProductItem> result = (List<ProductItem>) query.execute(10);

5. JDOQLタイプ

JDOQLTypedQueryAPIを使用するには、環境を準備する必要があります。

5.1. Mavenのセットアップ

<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-jdo-query</artifactId>
    <version>5.0.2</version>
</dependency>
...
<plugins>
    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

これらの依存関係の最新バージョンは、datanucleus-jdo-queryおよびmaven-compiler-pluginです。

5.2. 注釈処理の有効化

Eclipseの場合、以下の手順に従って、注釈付き処理を有効にすることができます。

  1. Javaコンパイラに移動し、コンパイラのコンプライアンスレベルが1.8以上であることを確認します
  2. Javaコンパイラ→注釈処理に移動し、プロジェクト固有の設定を有効にして、注釈処理を有効にします
  3. Javaコンパイラ→注釈処理→ファクトリパスに移動し、プロジェクト固有の設定を有効にしてから、次のjarをリストに追加します: javax.jdo.jar、 datanucleus-jdo -query.jar

上記の準備は、永続化可能なクラスをコンパイルするたびに、datanucleus-jdo-query.jarのアノテーションプロセッサが@PersistenceCapable。でアノテーションが付けられたクラスごとにクエリクラスを生成することを意味します。

この場合、プロセッサはQProductItemクラスを生成します。 生成されたクラスの名前は、接頭辞Qが付いていますが、永続化可能なクラスとほぼ同じです。

5.3. JDOQL型付きクエリを作成します。

JDOQLTypedQuery<ProductItem> tq = pm.newJDOQLTypedQuery(ProductItem.class);
QProductItem cand = QProductItem.candidate();
tq = tq.filter(cand.price.lt(10).and(cand.name.startsWith("pro")));
List<ProductItem> results = tq.executeList();

クエリクラスを利用して候補フィールドにアクセスし、使用可能なJavaメソッドを使用できます。

6. SQL

RDBMSを使用している場合、JDOはSQL言語をサポートします。

SQLクエリを作成しましょう:

Query query = pm.newQuery("javax.jdo.query.SQL","select * from "
  + "product_item where price < ? and status = ?");
query.setClass(ProductItem.class);
query.setParameters(10,"InStock");
List<ProductItem> results = query.executeList();

クエリの実行時にProductItemオブジェクトを取得するために、クエリに setClass()を使用しました。 それ以外の場合は、Objectタイプを取得します。

7. JPQL

JDODataNucleusはJPQL言語を提供します。

JPQLを使用してクエリを作成しましょう。

Query query = pm.newQuery("JPQL","select i from "
  + "com.baeldung.jdo.query.ProductItem i where i.price < 10"
  + " and i.status = 'InStock'");
List<ProductItem> results = (List<ProductItem>) query.execute();

ここでのエンティティ名は com.baeldung.jdo.query.ProductItem。 クラス名のみを使用することはできません。 これは、JDOにJPAのようなエンティティ名を定義するメタデータがないためです。 ProductItem p を定義し、その後、[ ProductItem。を参照するためのエイリアスとしてのX164X]p

JPQL構文の詳細については、このリンクを確認してください。

8. 結論

この記事では、JDOでサポートされているさまざまなクエリ言語を紹介しました。 名前付きクエリを保存して再利用する方法を示し、JDOQLの概念を説明し、SQLとJPQLをJDOで使用する方法を示しました。

この記事のコード例は、GitHubにあります。