送信チャネルアダプター
送信チャネルアダプターは受信の逆です。そのロールは、メッセージを処理し、それを使用して 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
を挿入して、各受信メッセージのクエリへのバインドを制御することもできます。
入力チャネルが直接チャネルの場合、送信アダプターはクエリを同じスレッドで実行するため、メッセージの送信者と同じトランザクション(存在する場合)を実行します。
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
モードを選択した場合、一括更新はサポートされません。