Cosminexus V9 アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)
CJPAプロバイダでは,JPQL以外のクエリ言語として,データベース固有のネイティブクエリを直接記述して,データベースの参照・更新などを実行できます。
ここでは,ネイティブクエリでの使用方法について説明します。
ネイティブクエリを使用してQueryオブジェクトを取得するためには,次に示すCJPAプロバイダが提供するEntityManagerインタフェースのメソッドを使用します。
createNativeQueryの記述例を次に示します。引数には実行するネイティブクエリを指定します。
Query q = em.createNativeQuery( "SELECT o.id, o.quantity, o.item " + "FROM Order o, Item i " + "WHERE (o.item = i.id) AND (i.name = 'widget')"); |
createNativeQueryの記述例を次に示します。第1引数には実行するネイティブクエリ,第2引数には実行結果を格納するクラスオブジェクトを指定します。
Query q = em.createNativeQuery( "SELECT o.id, o.quantity, o.item " + "FROM Order o, Item i " + "WHERE (o.item = i.id) AND (i.name = 'book')", com.hitachi.Order.class); |
この例の場合,クエリが実行されると「book」という名前のアイテムに対するすべてのOrderエンティティのコレクションを返します。
なお,SELECT節で指定したクエリの結果と引数に指定したクラスオブジェクトの整合性がない場合は例外が発生します。
第1引数には実行するネイティブクエリ,第2引数には実行結果を格納する結果セットマッピング名を指定します。結果セットマッピングは,@ SqlResultSetMappingで指定します。なお,結果セットマッピングについては,「(2) 結果セットマッピング」を参照してください。
@SqlResultSetMappingの定義例とcreateNativeQueryの記述例を次に示します。
@SqlResultSetMapping(name="BookOrderResults", entities=@EntityResult(entityClass=com.hitachi.Order.class)) |
Query q = em.createNativeQuery( "SELECT o.id, o.quantity, o.item " + "FROM Order o, Item i " + "WHERE (o.item = i.id) AND (i.name = 'book')", "BookOrderResults"); |
この例の場合,クエリが実行されると「book」という名前のアイテムに対するすべてのOrderエンティティのコレクションを返します。@SqlResultSetMappingを使用することで,「6.16.1(1) Queryオブジェクトの取得方法」の@NamedQueryを使用した場合の記述例と同じ結果を得ることができます。
なお,SELECT節で指定したクエリ結果と引数に指定した@SqlResultSetMapping設定の整合性がない場合は例外が発生します。
ネイティブクエリの場合も,JPQLと同じようにcreateNamedQueryメソッドを使用できます。ネイティブクエリの場合は,引数に名前付きネイティブクエリ名を指定してください。
名前付きネイティブクエリは,@NamedNativeQueryを任意のエンティティクラスに付与して定義します。引数のクエリ名には,@NamedNativeQueryのname属性で指定した名前を使用します。
CJPAプロバイダの場合,同じ名称の名前付きクエリを複数指定することはできません。同じ名称の名前付きクエリを複数指定した場合には,警告メッセージKDJE55522-Wを出力します。CJPAプロバイダで指定した場合,どのクエリが動作するかは保証しません。
次に,createNamedQueryメソッドの使用例を示します。この例では,@NamedNativeQueryを使用してあらかじめfindBookOrderという名前でクエリを登録しています。アプリケーションのcreateNamedQueryメソッドに登録した名前付きクエリ名を渡すことで,事前に登録されているクエリを取得して利用します。
@NamedNativeQuery( name="findBookOrder", query="SELECT o.id, o.quantity, o.item " +" "FROM Order o, Item i " + "WHERE (o.item = i.id) AND (i.name = 'book')") ) @Entity public class Order { ・・・ } |
@Stateless public class MySessionBean { ・・・ @PersistenceContext public EntityManager em; ・・・ public void doSomething() { ・・・ Query q = em.createNamedQuery("findBookOrder ") } } |
なお,同一の永続化ユニット内では,ほかのエンティティで定義した名前付きネイティブクエリを使用することもできます。
結果セットマッピングとは,ネイティブクエリの実行結果を任意のエンティティクラスにマッピングして受け取ったり,スカラ値で受け取ったりするための機能です。
結果セットマッピングでは,ネイティブクエリの実行結果として取得した各カラム値のマッピング情報を@SqlResultSetMappingを指定して任意のエンティティクラスに対して付与します。
@SqlResultSetMappingの記述形式を次に示します。
@SqlResultSetMapping( name= 結果セットマッピングの名前, entities= 結果をマッピングするためのエンティティクラス指定(@EntityResultの配列), columns= 結果をマッピングするためのカラム指定(@ColumnResultの配列) ) |
@EntityResult( entityClass= 結果をマッピングするためのクラスを指定, fields= 結果をマッピングするためのフィールド指定(@FieldResultの配列) ) |
@FiledResult( name= クラスの永続プロパティ(またはフィールド)の名前, column= SELECT節のカラムの名前(または別名) ) |
@ColumnResult( name= SELECT節のカラムの名前(または別名) ) |
従業員テーブル(Employee)と部門テーブル(Department)から従業員番号12003のクエリ結果を任意のエンティティクラス(EmployeeSetmap)にマッピングして,スカラ値(EMP_MONTHLY_SALARYカラム)を受け取る例を次に示します。
結果セットマッピング名(NativeQuerySetMap)をcreateNativeQueryの第2引数に指定して,結果セットマッピングを実行します。
query = em.createNativeQuery( "SELECT e.EMPLOYEE_ID AS EMP_EMPLOYEE_ID, " + "e.EMPLOYEE_NAME AS EMP_EMPLOYEE_NAME, " + "d.DEPARTMENT_NAME AS DEP_DEPARTMENT_NAME, " + "e.MONTHLY_SALARY AS EMP_MONTHLY_SALARY " + "FROM EMPLOYEE e, DEPARTMENT d " + "WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID " + "AND e.EMPLOYEE_ID = 12003", "NativeQuerySetMap"); |
@Entity public class EmployeeSetmap implements Serializable { : @Id public int getEmployeeId() { return employeeId; } public String getEmployeeName() { return employeeName; } public String getDepartmentName() { return departmentName; } : } |
@SqlResultSetMapping( name="NativeQuerySetmap", entities={ @EntityResult( entityClass=EmployeeSetmap.class, fields={ @FiledResult( name="employeeId", column="EMP_EMPLOYEE_ID"), @FiledResult( name="employeeName", column="EMP_EMPLOYEE_NAME"), @FiledResult( name="departmentName", column="DEP_DEPARTMENT_NAME") } ) }, columns={ @ColumnResult( name="EMP_MONTHLY_SALARY") } |
なお,@ SqlResultSetMappingを実行してネイティブクエリを実行した結果のObject型配列は,次のようになります。
ネイティブクエリは,JPQLと同様に,パラメタによって動的に値を設定することができます。WHERE節の中のパラメタを組み込みたい位置に,「?」と数値の組み合わせを記述します。パラメタの値は,QueryインタフェースのsetParameterメソッドで設定します。ただし,ネイティブクエリでは,JPQLの名前付きパラメタは使用できません。
パラメタの記述形式を次に示します。
Query setParameter(int 位置, Object 値) |
ネイティブクエリ結果の取得および実行は,JPQLと同様に,Queryインタフェースの次のメソッドを使用します。
これらのメソッドの詳細については,「6.16.1 JPQLでのデータベースの参照および更新方法」を参照してください。
All Rights Reserved. Copyright (C) 2012, 2015, Hitachi, Ltd.