CMP を使用する場合に設定する記述子要素がいくつかあります。
persistence-type
要素のコンテナを指定して、EJB によって CMP が使用されることを示します。
<persistence-type>Container</persistence-type>
prim-key-class
要素によってプライマリ キーのクラスを示します。<prim-key-class>ejbeans.BalanceKey</prim-key-class>
java.lang.Integer
などの Java プリミティブ ラッパー クラスを使用した場合、primkey-field
要素でプライマリ キー フィールドを指定します。<prim-key-class>java.lang.Integer</prim-key-class> <primkey-field>id</primkey-field>
cmp-field
要素を使用して、コンテナによってどのフィールドが管理されるかを指定します。コンテナで管理されるのは指定されたフィールドだけです。すべてのプライマリ キー フィールドを指定する必要があります。<cmp-field> <field-name>id</field-name> </cmp-field> <cmp-field> <field-name>value</field-name> </cmp-field>
env-entry
要素を指定します。これらの要素では、パーシスタンスを保つのに必要な SQL ステートメントを指定します。EJB エンジンでは、アクションのタイプごとに一連の env-entry
要素が必要です。次の表は、env-entry
の env-entry-name
要素で定義できるパーシスタンス アクションの一覧です。
env-entry-name 要素 |
説明 |
---|---|
ejipt.actionSQL |
データベースと対話する SQL ステートメントまたはストアド プロシージャの呼び出しを指定します。 |
ejipt.actionSQL.source |
JDBC ソースを示します。これは、JMC で定義された JRun データ ソースと一致する必要があります。 |
ejipt.actionSQL.params |
SQL ステートメント内の任意のパラメータに関連するフィールドの名前を表示順に示します。各パラメータは、「IN」(既定値)、「OUT」、または「INOUT」で修飾できます。パラメータ情報を指定するほかの方法については、"SQL ステートメントのパラメータ"を参照してください。 |
ejipt.actionSQL.paramTypes |
params プロパティで指定されているフィールドごとに JDBC データ タイプを表示順に示します。 |
ejipt.actionSQL.fields |
ResultSet に返される要素について、宛先フィールド名を表示順に示します。 |
次の表は、すべての可能なアクションと CMP 関連の env-entry-name
要素の一覧です。
次の例は、EJB サンプル 3a の公開記述子の env-entry を示します。
...
<!-- CMP properties --> <env-entry> <env-entry-name>ejipt.createSQL</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>INSERT INTO account (id, value) VALUES (?, ?) </env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.createSQL.source</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>source1</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.createSQL.params</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>_id, _value</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.createSQL.paramTypes</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>INTEGER, INTEGER</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.loadSQL</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>SELECT value FROM account WHERE id = ?</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.loadSQL.source</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>source1</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.loadSQL.params</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>_id</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.loadSQL.paramTypes</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>INTEGER</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.loadSQL.fields</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>_value</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.storeSQL</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>UPDATE account SET value = ?WHERE id = ?</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.storeSQL.source</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>source1</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.storeSQL.params</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>_value, _id</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.storeSQL.paramTypes</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>INTEGER, INTEGER</env-entry-value> </env-entry> ...
Bean では、1 つのパーシスタンス アクションについて複数の SQL ステートメントが必要になる場合があります。たとえば、1 つの Bean インスタンスで表されるデータを取得するために、複数の SQL ステートメントを使用することがあります。この場合は、次のように、SQL ステートメントの env-entry が追加されるたびに、env-entry にインデックスが関連付けられます。
...
ejipt.actionSQL ejipt.actionSQL.source ejipt.actionSQL.params ejipt.actionSQL.paramTypes ejipt.actionSQL.fields ejipt.actionSQL2 ejipt.actionSQL2.source ejipt.actionSQL2.params ejipt.actionSQL2.paramTypes ejipt.actionSQL2.fields ... ejipt.actionSQLn ejipt.actionSQLn.source ejipt.actionSQLn.params ejipt.actionSQLn.paramTypes ejipt.actionSQLn.fields ...
SQL ステートメントは、プロパティ名にあるインデックス順に昇順に実行されます。SQL ステートメントは無制限に追加できます。
CMP の場合、コンテナには、各メソッドに渡すパラメータに関する情報が必要です。この情報を使用して、SQL ステートメントの疑問符を実際の値に関連付けます。次のテクニックを使用してこれらの関連を指定します。
param
および paramTypes
env-entry を指定すると、コンテナでは Bean インスタンス変数を使用して、関連付けられている SQL で指定された疑問符を置き換えます。
コンテナで Bean 変数とメソッド引数を組み合わせて SQL ステートメントで指定された疑問符を置き換えるように、これらのメソッドを組み合わせることができます。
param
および paramTypes
env-entry を指定すると、コンテナでは Bean インスタンス変数を使用して、関連付けられている SQL で指定された疑問符を SQL ステートメントに表示される順序で置き換えます。たとえば、次のような env-entry
があります。
<env-entry>
<env-entry-name>ejipt.createSQL</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value> INSERT INTO account (id, value) VALUES (?, ?) </env-entry-value> </env-entry>
上記の例は、次の env-entry によって処理できます。
<env-entry>
<env-entry-name>ejipt.createSQL.params</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>_id, _value</env-entry-value> </env-entry> <env-entry> <env-entry-name>ejipt.createSQL.paramTypes</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>INTEGER, INTEGER</env-entry-value> </env-entry>
Bean インスタンス変数がヌルではないことを確認する必要があります。これは通常、ejbLoad
、ejbStore
、および ejbPostCreate
に関する問題ではありません。ただし、ejbCreate
の場合は、指定されたインスタンス変数が初期化されていることを確認するコードを追加する必要があります。たとえば、上記の env-entry を使用するには、次の ejbCreate
メソッドをコーディングします。
public void ejbCreate(int accountId)
throws CreateException, RemoteException { // CMP 用の Bean インスタンス変数を初期化します。 _id = accountId; _value = 0; }
詳細については、サンプル 3a の ejb-xml.jar
および BalanceBean.java
ファイルを参照してください。
メソッドの引数を使用して SQL を置き換える場合は、疑問符の後にメソッド引数内での位置を示す数字を付けて、SQL パラメータをメソッド引数に関連付けます。たとえば、コンテナでは ?1 をメソッドの最初の引数に、?2 をメソッドの 2 番目の引数にというように置き換えます。
このテクニックは、クエリ フィールドが必ずしも Bean インスタンス変数に対応するとは限らない複数行 finder メソッドに最も有効です。たとえば、このテクニックは、次の env-entry
に有効です。param
および paramTypes
env-entry は必要でないことに注意してください。
<env-entry>
<env-entry-name>ejipt.createSQL</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value> INSERT INTO account (id, value) VALUES (?1, ?2) </env-entry-value> </env-entry>
この env-entry
に対応する ejbCreate
メソッドには、次の例に示すように初期化コードは必要ありません。
public void ejbCreate(int accountId, int value)
throws CreateException, RemoteException { }