最新の安定バージョンについては、Spring Integration 7.1.0 を使用してください! |
送信チャネルアダプター
送信チャネルアダプターは受信の逆です。そのロールは、メッセージを処理し、それを使用して SQL クエリを実行することです。デフォルトでは、次の例に示すように、メッセージペイロードとヘッダーはクエリへの入力パラメーターとして使用できます。
<int-jdbc:outbound-channel-adapter
query="insert into items (id, status, name) values (:headers[id], 0, :payload[something])"
data-source="dataSource"
channel="input"/> 前の例では、input というラベルの付いたチャネルに到着するメッセージには、キーが something のマップのペイロードがあるため、[] オペレーターはその値をマップから逆参照します。ヘッダーは、マップとしてもアクセスされます。
上記のクエリのパラメーターは、受信メッセージの Bean プロパティ式です(SpEL 式ではありません)。この動作は SqlParameterSource の一部であり、これは送信アダプターによって作成されるデフォルトのソースです。異なる動作を得るために、異なる SqlParameterSourceFactory を注入できます。 |
送信アダプターには、DataSource または JdbcTemplate への参照が必要です。また、SqlParameterSourceFactory を挿入して、各受信メッセージのクエリへのバインディングを制御することもできます。SqlParameterSourceFactory (特にデフォルトの BeanPropertySqlParameterSourceFactory とその MapSqlParameterSource) をよりスムーズに使用するために、バージョン 6.5 以降、JdbcMessageHandler は、メッセージ全体をパラメーターソース入力として渡す必要があるかどうかを示す usePayloadAsParameterSource フラグを公開します。
入力チャネルが直接チャネルの場合、送信アダプターはクエリを同じスレッドで実行するため、メッセージの送信者と同じトランザクション(存在する場合)を実行します。
SpEL 式を使用してパラメーターを渡す
ほとんどの JDBC チャネルアダプターの一般的な要件は、SQL クエリまたはストアドプロシージャまたは関数の一部としてパラメーターを渡すことです。前述のように、これらのパラメーターはデフォルトでは Bean プロパティ式であり、SpEL 式ではありません。ただし、SpEL 式をパラメーターとして渡す必要がある場合は、明示的に SqlParameterSourceFactory を注入する必要があります。
次の例では、ExpressionEvaluatingSqlParameterSourceFactory を使用してその要件を実現しています。
<jdbc:outbound-channel-adapter data-source="dataSource" channel="input"
query="insert into MESSAGES (MESSAGE_ID,PAYLOAD,CREATED_DATE) values (:id, :payload, :createdDate)"
sql-parameter-source-factory="spelSource"/>
<bean id="spelSource"
class="o.s.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory">
<property name="parameterExpressions">
<map>
<entry key="id" value="headers['id'].toString()"/>
<entry key="createdDate" value="new java.util.Date()"/>
<entry key="payload" value="payload"/>
</map>
</property>
</bean>詳細については、パラメーターソースの定義を参照してください。
PreparedStatement コールバックの使用
場合によっては、SqlParameterSourceFactory の柔軟性と疎結合では、ターゲット PreparedStatement に必要なことを実行できないか、低レベルの JDBC 作業を行う必要があります。Spring JDBC モジュールは、実行環境(ConnectionCallback や PreparedStatementCreator など)を構成し、パラメーター値(SqlParameterSource など)を操作するための API を提供します。StatementCallback などの低レベル操作の API にもアクセスできます。
Spring Integration 4.2 以降、MessagePreparedStatementSetter では、requestMessage コンテキストで、PreparedStatement のパラメーターを手動で指定できます。このクラスは、標準の Spring JDBC API の PreparedStatementSetter とまったく同じロールを果たします。実際には、JdbcMessageHandler が JdbcTemplate で execute を呼び出すときに、インライン PreparedStatementSetter 実装から直接呼び出されます。
この関数インターフェースオプションは sqlParameterSourceFactory と相互に排他的であり、requestMessage から PreparedStatement のパラメーターを取り込むためのより強力な代替手段として使用できます。例: File データを DataBase BLOB 列にストリーミング方式で保存する必要がある場合に役立ちます。次の例は、その方法を示しています。
@Bean
@ServiceActivator(inputChannel = "storeFileChannel")
public MessageHandler jdbcMessageHandler(DataSource dataSource) {
JdbcMessageHandler jdbcMessageHandler = new JdbcMessageHandler(dataSource,
"INSERT INTO imagedb (image_name, content, description) VALUES (?, ?, ?)");
jdbcMessageHandler.setPreparedStatementSetter((ps, m) -> {
ps.setString(1, m.getHeaders().get(FileHeaders.FILENAME));
try (FileInputStream inputStream = new FileInputStream((File) m.getPayload())) {
ps.setBlob(2, inputStream);
}
catch (Exception e) {
throw new MessageHandlingException(m, e);
}
ps.setClob(3, new StringReader(m.getHeaders().get("description", String.class)));
});
return jdbcMessageHandler;
}XML 構成の観点から、prepared-statement-setter 属性は <int-jdbc:outbound-channel-adapter> コンポーネントで利用可能です。MessagePreparedStatementSetter Bean 参照を指定できます。
バッチ更新
バージョン 5.1 以降、リクエストメッセージのペイロードが Iterable インスタンスである場合、JdbcMessageHandler は JdbcOperations.batchUpdate() を実行します。Iterable の各要素は、そのような要素がまだ Message でない場合、リクエストメッセージからのヘッダーを使用して Message にラップされます。通常の SqlParameterSourceFactory ベースの構成の場合、これらのメッセージは、前述の JdbcOperations.batchUpdate() 関数で使用される引数の SqlParameterSource[] を構築するために使用されます。MessagePreparedStatementSetter 構成が適用されると、BatchPreparedStatementSetter バリアントを使用して各アイテムのメッセージが繰り返され、提供された MessagePreparedStatementSetter がそれらに対して呼び出されます。keysGenerated モードを選択した場合、一括更新はサポートされません。