名前付きクエリーの利用

ステータス:Early Access
Sean Brydon

課題

Java EE 5 アプリケーションは、Java Persistence API を使用してドメインモデルを作成します。エンティティーにアクセスするコードのデザインでは、クエリーを作成する必要があります。クエリーには動的に作成されるものもあれば、静的なクエリーもあります。静的クエリーは、パラメータを受け取ることはできますが、変更されることはありません。アプリケーションが大きくなると、コードのクエリーが大量になり、管理が難しくなることがあります。

対処法

Java Persistence API では、定義済みクエリーに名前付きクエリーを作成できます。コードで Query API を利用すると、名前付きクエリーを使用することができます。何回か実行していて、パラメータを設定するだけのクエリーには、いつでも名前付きクエリーを使用できます。そうしたクエリーは、よく静的クエリーと呼ばれます。事前定義済みのあらゆるクエリーに、名前付きクエリーを利用できます。

名前付きクエリーを利用することで、次の利点があります。

名前付きクエリーは、多くのクラスやインスタンスによる再利用を行うため、スレッドセーフです。名前付きクエリーの名前はスコープを持っていて、名前の衝突を避けることが重要です。名前付きクエリーを定義するために注釈を使用する場合、その名前のスコープが持続性ユニット内に表示されます。配備記述子を使用して、アプリケーションスコープで名前を表示させることができます。コード内で名前付きクエリーを使用する場合、クエリー名の前方部分で名前付きクエリーが定義されるというように、そのクラスのクラス名に接頭辞を付ける命名規則を使用します。

名前付きクエリーは特定のクラスでしか定義できません。名前付きクエリーは、エンティティーおよびマップされたスーパークラス上にのみ定義され、配置されます。

名前付きクエリーは、ネイティブの SQL クエリーおよび Java Persistence クエリー言語で表現されたクエリーで使用できます。

名前付きクエリーを使用するためのコードのリファクタリング

名前付きクエリーの考え方は単純で有用です。名前付きクエリーはネイティブの SQL クエリーでも同様に使用できますが、ここで使用する例は、Java Persistence クエリー言語で作成したクエリーを対象にしています。

名前付きクエリーの利用前 名前付きクエリーの利用後
public class MyDataFacade ... {
  private EntityManager em;
  ...
  public List<Items> getItems(String catID){
    Query query =
    em.createQuery("SELECT i FROM Item i WHERE i.product.categoryID LIKE :cID");
   
query.setParameter ("cID",catID);

    List<Item> items = query.getResultList();
    return item;
  }


このコードでは、クエリーを文字列型定数に入れていますが、プリコンパイルはされません。

クラスで注釈が使用されています:

@NamedQuery(
  name="
MyEntity.getItemsPerProductCategory",
  query="SELECT i FROM Item i WHERE i.product.categoryID LIKE :cID"
)
@Entity
public class MyEntity { ...

Then another class uses the named queries...
public class MyDataFacade ... {
  private EntityManager em;
  ...
  public List<Items> getItems(String catID) {
    Query query =
 em.createNamedQuery("MyEntity.getItemsPerProductCategory");     query.setParameter("cID",catID);

    List<Item> items = query.getResultList();
    return item;
  }

前述の例から分かるように、コードをリファクタリングして名前付きクエリーを利用するのはとても簡単です。

名前付きクエリーのマイナーデザインの選択の 1 つとして、定位置パラメータまたは名前付きパラメータを使用するかどうかがあります。コードが理解しやすく、保守しやすいため、名前付きパラメータのほうが好まれます。前述のコード例では、query.setParameter("cID",catID) を呼び出すことによって値が設定される名前付きパラメータ ":cID" with query="SELECT i FROM Item i WHERE i.product.categoryID LIKE :cID" を使用した名前付きクエリーを示しています。コードがすっきりしていて簡単です。

NamedQueries 注釈の使用

1 つ以上の名前付きクエリーがある場合は、NamedQueries 注釈を使用して、クラス内で使用されるすべての名前付きクエリーの一覧を作成できます。次は、その使用例です。クラスで注釈が使用されています。
@NamedQueries(
{
@NamedQuery(
name="
MyEntity.getItemsPerProductCategory",
query="SELECT i FROM Item i WHERE i.productID.categoryID LIKE :cID"
),
@NamedQuery(
name="
MyEntity.getAllZipCityState",
query="SELECT z FROM ZipLocation z"
)
}
)
@Entity
public class MyEntity {...

こうして、コードで、各名前付きクエリーを通常の方法で使用できます。

public class MyDataFacade ... {
...
Query query = em.createNamedQuery("
MyEntity.getItemsPerProductCategory");
名前付きクエリーを一覧表示する構文は、最初はわかりにくいですが、かなり単純です。

参考資料

次に参考資料を挙げます。

© Sun Microsystems 2006. Java BluePrints Solutions Catalog の内容はすべて著作権保護されており、サン・マイクロシステムズ社の書面による許可なしに他の著作物に発表することを禁止します。