ストアドプロシージャー
特定の状況では、プレーンな JDBC サポートでは不十分です。おそらく、従来のリレーショナルデータベーススキーマを扱うか、複雑なデータ処理のニーズがありますが、最終的には、ストアドプロシージャ [Wikipedia] (英語) またはストアドファンクションを使用する必要があります。Spring Integration 2.1 以降、ストアドプロシージャまたはストアドファンクションを実行する 3 つのコンポーネントを提供しています。
ストアドプロシージャの受信チャネルアダプター
ストアドプロシージャの送信チャネルアダプター
ストアドプロシージャの送信ゲートウェイ
サポートされているデータベース
ストアドプロシージャとストアドファンクションの呼び出しを可能にするために、ストアドプロシージャコンポーネントは org.springframework.jdbc.core.simple.SimpleJdbcCall
(Javadoc) クラスを使用します。ストアドプロシージャの実行では、次のデータベースが完全にサポートされています。
Apache Derby
DB2
MySQL
Microsoft SQL Server
Oracle
PostgreSQL
Sybase
代わりにストアド関数を実行する場合、次のデータベースが完全にサポートされます。
MySQL
Microsoft SQL Server
Oracle
PostgreSQL
特定のデータベースが完全にサポートされていない場合でも、RDBMS がストアドプロシージャまたはストアド関数をサポートしていれば、ストアドプロシージャ Spring Integration コンポーネントを非常にうまく使用できる可能性があります。 実際のところ、提供されている統合テストの中には H2 データベース (英語) を使用しているものがあります。それでも、これらの使用シナリオを徹底的にテストすることは非常に重要です。 |
共通の構成属性
すべてのストアドプロシージャコンポーネントは、特定の構成パラメーターを共有します。
auto-startup
: アプリケーションコンテキストの起動時にこのコンポーネントを起動する必要があるかどうかを示すライフサイクル属性。デフォルトはtrue
です。オプション。data-source
: データベースへのアクセスに使用されるjavax.sql.DataSource
への参照。必須。id
: 発信チャネルアダプターのchannel
属性がSubscribableChannel
またはPollableChannel
のどちらを参照するかに応じて、基になる Spring Bean 定義を識別します。これは、EventDrivenConsumer
またはPollingConsumer
のいずれかのインスタンスです。オプション。ignore-column-meta-data
: 完全にサポートされているデータベースの場合、基になるSimpleJdbcCall
(Javadoc) クラスは、JDBC メタデータからストアドプロシージャまたはストアドファンクションのパラメーター情報を自動的に取得できます。ただし、データベースがメタデータ検索をサポートしていない場合、またはカスタマイズされたパラメーター定義を提供する必要がある場合、このフラグを
true
に設定できます。デフォルトはfalse
です。オプション。is-function
:true
の場合、SQL 関数が呼び出されます。その場合、stored-procedure-name
またはstored-procedure-name-expression
属性は、呼び出された関数の名前を定義します。デフォルトはfalse
です。オプション。stored-procedure-name
: この属性は、ストアドプロシージャの名前を指定します。is-function
属性がtrue
に設定されている場合、この属性は代わりに関数名を指定します。このプロパティまたはstored-procedure-name-expression
のいずれかを指定する必要があります。stored-procedure-name-expression
: この属性は、SpEL 式を使用してストアドプロシージャの名前を指定します。SpEL を使用すると、ヘッダーとペイロードを含む完全なメッセージ(利用可能な場合)にアクセスできます。この属性を使用して、実行時にさまざまなストアドプロシージャを呼び出すことができます。例: メッセージヘッダーとして実行するストアドプロシージャ名を指定できます。式はString
に解決する必要があります。is-function
属性がtrue
に設定されている場合、この属性はストアド関数を指定します。このプロパティまたはstored-procedure-name
のいずれかを指定する必要があります。jdbc-call-operations-cache-size
: キャッシュされるSimpleJdbcCallOperations
インスタンスの最大数を定義します。基本的に、ストアドプロシージャ名ごとに、新しいSimpleJdbcCallOperations
(Javadoc) インスタンスが作成され、そのインスタンスがキャッシュされます。Spring Integration 2.2 は、 stored-procedure-name-expression
属性とjdbc-call-operations-cache-size
属性を追加しました。デフォルトのキャッシュサイズは
10
です。0
の値はキャッシュを無効にします。負の値は許可されていません。JMX を有効にすると、
jdbc-call-operations-cache
に関する統計情報が MBean として公開されます。詳細については、MBean エクスポーターを参照してください。sql-parameter-source-factory
: (ストアードプロシージャーの受信・チャネルアダプターには使用できません)SqlParameterSourceFactory
への参照。デフォルトでは、渡されたMessage
ペイロードの Bean プロパティは、BeanPropertySqlParameterSourceFactory
を使用して、ストアドプロシージャの入力パラメーターのソースとして使用されます。これは基本的な使用例で十分です。より高度なオプションについては、1 つ以上の
ProcedureParameter
値を渡すことを検討してください。パラメーターソースの定義を参照してください。オプション。use-payload-as-parameter-source
: (ストアードプロシージャーの受信・チャネルアダプターでは使用できません)true
に設定されている場合、Message
のペイロードはパラメーターを提供するためのソースとして使用されます。ただし、false
に設定すると、Message
全体がパラメーターのソースとして使用可能になります。プロシージャパラメーターが渡されない場合、このプロパティのデフォルトは
true
になります。これは、デフォルトのBeanPropertySqlParameterSourceFactory
を使用することにより、ペイロードの Bean プロパティがストアドプロシージャまたはストアドファンクションのパラメーター値のソースとして使用されることを意味します。ただし、プロシージャパラメーターが渡された場合、このプロパティは (デフォルトで)
false
と評価されます。ProcedureParameter
では SpEL 式を提供できます。Message
全体にアクセスできることは非常に有益です。基礎となるStoredProcExecutor
に設定されるプロパティ。オプション。
共通の構成サブ要素
ストアドプロシージャコンポーネントは、パラメーターを定義してストアドプロシージャまたはストアド関数に渡すために使用できる子要素の共通セットを共有します。以下の要素が利用可能です:
parameter
returning-resultset
sql-parameter-definition
poller
parameter
: ストアドプロシージャのパラメーターを提供するメカニズムを提供します。パラメーターは静的にすることも、SpEL 式を使用して提供することもできます。<int-jdbc:parameter name="" (1) type="" (2) value=""/> (3) <int-jdbc:parameter name="" expression=""/> (4)
1 ストアドプロシージャまたはストアド関数に渡されるパラメーターの名前。必須。 2 この属性は値の型を指定します。何も指定しない場合、この属性はデフォルトで java.lang.String
になります。この属性は、value
属性が使用されている場合にのみ使用されます。オプション。3 パラメーターの値。この属性または expression
属性のいずれかを指定する必要があります。オプション。4 value
属性の代わりに、パラメーターの値を渡すための SpEL 式を指定できます。expression
を指定した場合、value
属性は許可されません。オプション。オプション。returning-resultset
: ストアドプロシージャは複数の結果セットを返す場合があります。1 つ以上のreturning-resultset
要素を設定することにより、RowMappers
を指定して、返された各ResultSet
を意味のあるオブジェクトに変換できます。オプション。<int-jdbc:returning-resultset name="" row-mapper="" />
sql-parameter-definition
: 完全にサポートされているデータベースを使用する場合、通常、ストアドプロシージャのパラメーター定義を指定する必要はありません。代わりに、これらのパラメーターは JDBC メタデータから自動的に派生できます。ただし、完全にサポートされていないデータベースを使用する場合は、sql-parameter-definition
要素を使用してこれらのパラメーターを明示的に設定する必要があります。ignore-column-meta-data
属性を使用して、JDBC を介して取得したパラメーターメタデータ情報の処理をオフにすることもできます。<int-jdbc:sql-parameter-definition name="" (1) direction="IN" (2) type="STRING" (3) scale="5" (4) type-name="FOO_STRUCT" (5) return-type="fooSqlReturnType"/> (6)
1 | SQL パラメーターの名前を指定します。必須。 |
2 | SQL パラメーター定義の方向を指定します。デフォルトは IN です。有効な値は次のとおりです: IN 、OUT 、INOUT 。プロシージャが結果セットを返す場合は、returning-resultset 要素を使用してください。オプション。 |
3 | この SQL パラメーター定義に使用される SQL 型。java.sql.Types で定義されている整数値に変換します。または、整数値も提供できます。この属性が明示的に設定されていない場合、デフォルトは "VARCHAR" です。オプション。 |
4 | SQL パラメーターのスケール。数値および小数のパラメーターにのみ使用されます。オプション。 |
5 | STRUCT 、DISTINCT 、JAVA_OBJECT などのユーザー指定の型および名前付き配列型の typeName 。この属性は、scale 属性と相互に排他的です。オプション。 |
6 | 複合型のカスタム値ハンドラーへの参照。SqlReturnType (Javadoc) の実装。この属性は scale 属性と相互に排他的であり、OUT および INOUT パラメーターにのみ適用可能です。オプション。
|
パラメーターソースの定義
パラメーターソースは、Spring Integration メッセージプロパティを取得し、関連するストアドプロシージャの入力パラメーターにマッピングする手法を管理します。
ストアドプロシージャコンポーネントは、特定の規則に従います。デフォルトでは、Message
ペイロードの Bean プロパティは、ストアドプロシージャの入力パラメーターのソースとして使用されます。その場合、BeanPropertySqlParameterSourceFactory
が使用されます。これは基本的な使用例で十分です。次の例は、デフォルトの動作を示しています。
BeanPropertySqlParameterSourceFactory を使用した Bean プロパティの「自動」ルックアップを機能させるには、Bean プロパティを小文字で定義する必要があります。これは、org.springframework.jdbc.core.metadata.CallMetaDataContext (Java メソッドは matchInParameterValuesWithCallParameters() )では、取得されたストアドプロシージャのパラメーター宣言が小文字に変換されるためです。その結果、キャメルケース Bean プロパティ(lastName など)がある場合、検索は失敗します。その場合、明示的な ProcedureParameter を提供します。 |
次の 3 つのプロパティを持つ単純な Bean で構成されるペイロードがあるとします: id
、name
、description
。さらに、id
、name
、description
という 3 つの入力パラメーターを受け入れる INSERT_COFFEE
と呼ばれる単純なストアドプロシージャがあります。また、完全にサポートされているデータベースを使用しています。その場合、ストアードプロシージャーの送信・アダプターの以下の構成で十分です。
<int-jdbc:stored-proc-outbound-channel-adapter data-source="dataSource"
channel="insertCoffeeProcedureRequestChannel"
stored-procedure-name="INSERT_COFFEE"/>
より高度なオプションについては、1 つ以上の ProcedureParameter
値を渡すことを検討してください。
ProcedureParameter
値を明示的に指定した場合、デフォルトでは、ExpressionEvaluatingSqlParameterSourceFactory
がパラメーター処理に使用され、SpEL 式のフルパワーが有効になります。
パラメーターの取得方法をさらに制御する必要がある場合は、sql-parameter-source-factory
属性を使用して SqlParameterSourceFactory
のカスタム実装を渡すことを検討してください。
ストアドプロシージャ受信チャネルアダプター
次のリストは、ストアドプロシージャ受信チャネルアダプターに関係する属性を示しています。
<int-jdbc:stored-proc-inbound-channel-adapter
channel="" (1)
stored-procedure-name=""
data-source=""
auto-startup="true"
id=""
ignore-column-meta-data="false"
is-function="false"
skip-undeclared-results="" (2)
return-value-required="false" (3)
<int:poller/>
<int-jdbc:sql-parameter-definition name="" direction="IN"
type="STRING"
scale=""/>
<int-jdbc:parameter name="" type="" value=""/>
<int-jdbc:parameter name="" expression=""/>
<int-jdbc:returning-resultset name="" row-mapper="" />
</int-jdbc:stored-proc-inbound-channel-adapter>
1 | ポーリングされたメッセージが送信されるチャネル。ストアドプロシージャまたは関数がデータを返さない場合、Message のペイロードは null です。必須。 |
2 | この属性が true に設定されている場合、対応する SqlOutParameter 宣言を持たないストアドプロシージャコールの結果はすべてバイパスされます。例: ストアドプロシージャが単一の結果パラメーターのみを宣言している場合でも、ストアドプロシージャは更新カウント値を返すことができます。正確な動作は、データベースの実装に依存します。値は、基礎となる JdbcTemplate に設定されます。値のデフォルトは true です。オプション。 |
3 | このプロシージャの戻り値を含めるかどうかを示します。Spring Integration 3.0 以降。オプション。 |
ストアドプロシージャの送信チャネルアダプター
次のリストは、ストアドプロシージャの送信チャネルアダプターに重要な属性を示しています。
<int-jdbc:stored-proc-outbound-channel-adapter channel="" (1)
stored-procedure-name=""
data-source=""
auto-startup="true"
id=""
ignore-column-meta-data="false"
order="" (2)
sql-parameter-source-factory=""
use-payload-as-parameter-source="">
<int:poller fixed-rate=""/>
<int-jdbc:sql-parameter-definition name=""/>
<int-jdbc:parameter name=""/>
</int-jdbc:stored-proc-outbound-channel-adapter>
1 | このエンドポイントの受信メッセージチャネル。必須。 |
2 | このエンドポイントがチャンネルのサブスクライバーとして接続されている場合の呼び出しの順序を指定します。これは、そのチャネルが failover ディスパッチ戦略を使用している場合に特に重要です。このエンドポイント自体がキューを持つチャネルのポーリングコンシューマーである場合、効果はありません。オプション。 |
ストアドプロシージャの送信ゲートウェイ
次のリストは、ストアドプロシージャの送信チャネルアダプターに重要な属性を示しています。
<int-jdbc:stored-proc-outbound-gateway request-channel="" (1)
stored-procedure-name=""
data-source=""
auto-startup="true"
id=""
ignore-column-meta-data="false"
is-function="false"
order=""
reply-channel="" (2)
reply-timeout="" (3)
return-value-required="false" (4)
skip-undeclared-results="" (5)
sql-parameter-source-factory=""
use-payload-as-parameter-source="">
<int-jdbc:sql-parameter-definition name="" direction="IN"
type=""
scale="10"/>
<int-jdbc:sql-parameter-definition name=""/>
<int-jdbc:parameter name="" type="" value=""/>
<int-jdbc:parameter name="" expression=""/>
<int-jdbc:returning-resultset name="" row-mapper="" />
1 | このエンドポイントの受信メッセージチャネル。必須。 |
2 | データベースレスポンスを受信した後、レスポンスが送信されるメッセージチャネル。オプション。 |
3 | このゲートウェイが例外をスローする前に応答メッセージが正常に送信されるまで待機する時間を指定できます。DirectChannel に送信する場合、呼び出しは送信者のスレッドで発生することに注意してください。送信操作の失敗は、さらに下流の他のコンポーネントによって引き起こされる可能性があります。値はミリ秒単位で指定します。オプション。 |
4 | このプロシージャの戻り値を含めるかどうかを示します。オプション。 |
5 | skip-undeclared-results 属性が true に設定されている場合、対応する SqlOutParameter 宣言を持たないストアドプロシージャコールの結果はすべてバイパスされます。例: ストアドプロシージャが単一の結果パラメーターのみを宣言している場合でも、ストアドプロシージャは更新カウント値を返すことがあります。正確な動作はデータベースによって異なります。値は、基礎となる JdbcTemplate に設定されます。値のデフォルトは true です。オプション。 |
サンプル
このセクションには、Apache Derby (英語) ストアドプロシージャを呼び出す 2 つの例が含まれています。最初のプロシージャは、ResultSet
を返すストアドプロシージャを呼び出します。RowMapper
を使用することにより、データはドメインオブジェクトに変換され、その後、Spring Integration メッセージペイロードになります。
2 番目のサンプルでは、代わりに出力パラメーターを使用してデータを返すストアドプロシージャを呼び出します。
Spring Integration サンプルプロジェクト [GitHub] (英語) を参照してください。 プロジェクトには、ここで参照されている Apache Derby の例と、その実行メソッドの説明が含まれています。Spring Integration サンプルプロジェクトには、Oracle ストアドプロシージャの使用例 [GitHub] (英語) も用意されています。 |
最初の例では、FIND_ALL_COFFEE_BEVERAGES
という名前のストアドプロシージャを呼び出します。このストアドプロシージャは、入力パラメーターを定義しませんが、ResultSet
を返します。
Apache Derby では、ストアドプロシージャは Java で実装されています。次のリストはメソッドシグネチャーを示しています。
public static void findAllCoffeeBeverages(ResultSet[] coffeeBeverages)
throws SQLException {
...
}
次のリストは、対応する SQL を示しています。
CREATE PROCEDURE FIND_ALL_COFFEE_BEVERAGES() \
PARAMETER STYLE JAVA LANGUAGE JAVA MODIFIES SQL DATA DYNAMIC RESULT SETS 1 \
EXTERNAL NAME 'o.s.i.jdbc.storedproc.derby.DerbyStoredProcedures.findAllCoffeeBeverages';
Spring Integration では、次の例に示すように、たとえば stored-proc-outbound-gateway
を使用して、このストアドプロシージャを呼び出すことができます。
<int-jdbc:stored-proc-outbound-gateway id="outbound-gateway-storedproc-find-all"
data-source="dataSource"
request-channel="findAllProcedureRequestChannel"
expect-single-result="true"
stored-procedure-name="FIND_ALL_COFFEE_BEVERAGES">
<int-jdbc:returning-resultset name="coffeeBeverages"
row-mapper="org.springframework.integration.support.CoffeBeverageMapper"/>
</int-jdbc:stored-proc-outbound-gateway>
2 番目の例では、1 つの入力パラメーターを持つ FIND_COFFEE
という名前のストアドプロシージャを呼び出します。ResultSet
を返す代わりに、出力パラメーターを使用します。次の例は、メソッドのシグネチャーを示しています。
public static void findCoffee(int coffeeId, String[] coffeeDescription)
throws SQLException {
...
}
次のリストは、対応する SQL を示しています。
CREATE PROCEDURE FIND_COFFEE(IN ID INTEGER, OUT COFFEE_DESCRIPTION VARCHAR(200)) \
PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME \
'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.findCoffee';
Spring Integration では、次の例に示すように、たとえば stored-proc-outbound-gateway
を使用して、このストアドプロシージャを呼び出すことができます。
<int-jdbc:stored-proc-outbound-gateway id="outbound-gateway-storedproc-find-coffee"
data-source="dataSource"
request-channel="findCoffeeProcedureRequestChannel"
skip-undeclared-results="true"
stored-procedure-name="FIND_COFFEE"
expect-single-result="true">
<int-jdbc:parameter name="ID" expression="payload" />
</int-jdbc:stored-proc-outbound-gateway>