第79章 JDBC


JDBC コンポーネント

JDBC コンポーネントを使用すると、JDBC 経由でデータベースにアクセスできます。ここでは、SQL クエリー(SELECT)および操作(INSERTUPDATE など)がメッセージボディーに送信されます。このコンポーネントは、spring-jdbc を使用する SQL Component コンポーネントとは異なり、標準の JDBC API を使用します。
警告
このコンポーネントはプロデューサーエンドポイントを定義する場合にのみ使用できます。つまり、from () ステートメントで JDBC コンポーネントを使用することはできません。

URI 形式

jdbc:dataSourceName[?options]
Copy to Clipboard Toggle word wrap
このコンポーネントはプロデューサーエンドポイントのみをサポートします。
URI にクエリーオプションは ?option=value&option=value&.. の形式で追加できます。

オプション

Expand
名前 デフォルト値 説明
readSize 0 ポーリングクエリーで読み取り可能なデフォルトの最大行数。
statement.<xxx> null Apache Camel 2.1: クエリーを実行するために背後で使用される java.sql.Statement に追加のオプションを設定します。たとえば、statement.maxRows=10 を使用します。詳細なドキュメントは、java.sql.Statement javadoc のドキュメント を参照してください。
useJDBC4ColumnNameAndLabelSemantics true JDBC 4/3 列ラベル/名前セマンティクスを使用するかどうかを設定します。JDBC ドライバーでデータを選択する場合に、このオプションを使用して false にすることができます。これは、エイリアスを使用し SQL SELECT を使用する場合にのみ適用されます(例:SQL SELECT id を識別子、persons から given_name のような名前)。
resetAutoCommit true Camel 2.9: true の場合、Camel は JDBC 接続の autoCommitfalse に設定し、ステートメントを実行した後に変更をコミットし、最後に接続の autoCommit フラグをリセットします。JDBC 接続が autoCommit フラグのリセットをサポートしていない場合は、これを false に設定します。XA トランザクションと併用する場合は、トランザクションマネージャーがこの tx のコミットを担当するように、ほとんどの場合 false に設定する必要があります。
allowNamedParameters true Camel 2.12: クエリーで名前付きパラメーターの使用を許可するかどうか。
prepareStatementStrategy Camel 2.12: プラグインがカスタムの org.apache.camel.component.jdbc.JdbcPrepareStatementStrategy を使用して、クエリーおよび準備済みステートメントの準備を制御できます。
useHeadersAsParameters false Camel 2.12: 名前付きパラメーターで prepareStatementStrategy を使用するには、このオプションを true に設定します。これにより、名前付きプレースホルダーでクエリーを定義し、クエリープレースホルダーの動的な値でヘッダーを使用できます。
outputType SelectList
Camel 2.12.1: producer to SelectList as List of Map, or SelectOne as single Java object in the following way: a)クエリーに列が 1 つしかない場合は、その JDBC Column オブジェクトが返されます。SELECT COUNT (*) FROM PROJECT (SELECT COUNT (*) FROM PROJECT など)-Long オブジェクトを返します。b (クエリーに複数の列がある場合) その結果の Map を返します。c)outputClass が設定されている場合には、列名に一致するすべてのセッターを呼び出すことで、クエリー結果を Java Bean オブジェクトに変換します。クラスにインスタンスを作成するデフォルトのコンストラクターがあるとします。Camel 2.14 以降では、SelectList もサポートされます。d)クエリーによって複数の行が発生した場合、一意でない結果例外が出力されます。
Camel 2.14.0: 新しい StreamList 出力タイプ値。Iterator<Map<String, Object>> を使用してクエリーの結果をストリーミングします。Splitter EIP と併用できます。
outputClass null Camel 2.12.1: outputType=SelectOne の場合に変換として使用する完全なパッケージおよびクラス名を指定します。Camel 2.14 以降では、SelectList もサポートされます。
beanRowMapper Camel 2.12.1: outputClass の使用時にカスタム org.apache.camel.component.jdbc.BeanRowMapper を使用するには、以下を行います。デフォルトの実装では、行名が低くなり、アンダースコアやダッシュをスキップします。たとえば、CUST_ID は cust Id としてマッピングされます
useGetBytesForBlob false Camel 2.16: BLOB 列を文字列データではなくバイトとして読み取る。これは、BLOB 列をバイトとして読み取る必要がある Oracle などの特定のデータベースで必要になる場合があります。

結果

デフォルトでは、結果は OUT ボディーに ArrayList<HashMap<String, Object>> として返されますList オブジェクトには行のリストが含まれ、Map オブジェクトには、String キーを持つ各行が列名として含まれます。
注記
このコンポーネントは ResultSetMetaData を取得し、列名を Map のキーとして返すことができます。

メッセージヘッダー

Expand
ヘッダー 説明
CamelJdbcRowCount クエリーが SELECT の場合、行数はこの OUT ヘッダーで返されます。
CamelJdbcUpdateCount クエリーが UPDATE の場合、更新数はこの OUT ヘッダーで返されます。
CamelGeneratedKeysRows Camel 2.10: 生成された kets が含まれる行。
CamelGeneratedKeysRowCount Camel 2.10: 生成されたキーが含まれるヘッダーの行数。
CamelJdbcColumnNames Camel 2.11.1: ResultSet からの列名( java.util.Set 型)
CamelJdbcParametes Camel 2.12: useHeadersAsParameters が有効な場合に使用されるヘッダーを持つ java.util.Map

生成されるキー

Camel 2.10 以降で利用可能
SQL INSERT を使用してデータを挿入すると、----------|----- は自動生成されたキーをサポートする可能性があります。JDBC プロデューサーに対して、ヘッダーで生成されたキーを返すように指示できます。これには、ヘッダー CamelRetrieveGeneratedKeys=true を設定します。次に、生成された鍵が上記の表に記載されているキーが含まれるヘッダーとして提供されます。
from("direct:insert")
  .setHeader("CamelRetrieveGeneratedKeys", constant(true))
  .setBody(constant("INSERT INTO projects (project) VALUES ('Camel')"))
  .to("jdbc:myDataSource");
Copy to Clipboard Toggle word wrap
詳細は、この ユニットテスト を参照してください。
重要
生成された鍵を使用することは、名前付きパラメーターと併用できません。

名前付きパラメーターの使用

Camel 2.12 以降で利用可能
以下のルートでは、Projects テーブルからすべてのプロジェクトを取得します。SQL クエリーには、:?lic と :?min の 2 つの名前付きパラメーターがあることに注意してください。Camel はメッセージヘッダーからこれらのパラメーターを検索します。上記の例では、名前付きパラメーターに定数値で 2 つのヘッダーを設定することに注意してください。
  from("direct:projects")
     .setHeader("lic", constant("ASF"))
     .setHeader("min", constant(123))
     .setBody(constant("select * from projects where license = :?lic and id > :?min order by id"))
     .to("jdbc:myDataSource?useHeadersAsParameters=true")
Copy to Clipboard Toggle word wrap
ヘッダー値を java.util.Map に保存し、キー CamelJdbcParameters を使用してヘッダーにマッピングすることもできます。

サンプル

以下の例では、customers テーブルから行を取得します。
最初に、データソースを testdb として Apache Camel レジストリーに登録します。
JndiRegistry reg = super.createRegistry();
reg.bind("testdb", db);
return reg;
Copy to Clipboard Toggle word wrap
次に、JDBC コンポーネントにルーティングするルートを設定し、SQL が実行されます。前の手順でバインドされた testdb データソースを参照する方法に注意してください。
// lets add simple route
public void configure() throws Exception {
    from("direct:hello").to("jdbc:testdb?readSize=100");
}
Copy to Clipboard Toggle word wrap
または、以下のように Spring で DataSource を作成することもできます。
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <route>
	 <!-- trigger every second -->
     <from uri="timer://kickoff?period=1s"/>
     <setBody>
       <constant>select * from customer</constant>
     </setBody>
     <to uri="jdbc:testdb"/>
     <to uri="mock:result"/>
  </route>
</camelContext>
<!-- Just add a demo to show how to bind a date source for camel in Spring-->
<jdbc:embedded-database id="testdb" type="DERBY">
	<jdbc:script location="classpath:sql/init.sql"/>
</jdbc:embedded-database>
Copy to Clipboard Toggle word wrap
エンドポイントを作成し、SQL クエリーを IN メッセージのボディーに追加してから、エクスチェンジを送信します。クエリーの結果は OUT ボディーで返されます。
// first we create our exchange using the endpoint
Endpoint endpoint = context.getEndpoint("direct:hello");
Exchange exchange = endpoint.createExchange();
// then we set the SQL on the in body
exchange.getIn().setBody("select * from customer order by ID");

// now we send the exchange to the endpoint, and receives the response from Camel
Exchange out = template.send(endpoint, exchange);

// assertions of the response
assertNotNull(out);
assertNotNull(out.getOut());
List<Map<String, Object>> data = out.getOut().getBody(List.class);
assertNotNull(data);
assertEquals(3, data.size());
Map<String, Object> row = data.get(0);
assertEquals("cust1", row.get("ID"));
assertEquals("jstrachan", row.get("NAME"));
row = data.get(1);
assertEquals("cust2", row.get("ID"));
assertEquals("nsandhu", row.get("NAME"));
Copy to Clipboard Toggle word wrap
ResultSet 全体ではなく、一度に 1 行ずつ作業する場合は、以下のような Splitter EIP を使用する必要があります。
from("direct:hello")
// here we split the data from the testdb into new messages one by one
// so the mock endpoint will receive a message per row in the table
// the StreamList option allows to stream the result of the query without creating a List of rows
// and notice we also enable streaming mode on the splitter
.to("jdbc:testdb?outputType=StreamList")
  .split(body()).streaming()
  .to("mock:result");
Copy to Clipboard Toggle word wrap

サンプル:データベースを毎分ポーリングする

JDBC コンポーネントを使用してデータベースをポーリングする場合は、TimerQuartz などのポーリングスケジューラーと組み合わせる必要があります。以下の例では、60 秒ごとにデータベースからデータを取得します。
from("timer://foo?period=60000").setBody(constant("select * from customer")).to("jdbc:testdb").to("activemq:queue:customers");
Copy to Clipboard Toggle word wrap

例:データソース間のデータの移動

一般的なユースケースは、データをクエリーし、処理して別のデータソース(ETL 操作)に移動することです。以下の例では、1 時間ごとに新しい顧客レコードを取得し、それらをフィルターリング/変換し、宛先テーブルに移動します。
from("timer://MoveNewCustomersEveryHour?period=3600000")
    .setBody(constant("select * from customer where create_time > (sysdate-1/24)"))
    .to("jdbc:testdb")
    .split(body())
		.process(new MyCustomerProcessor()) //filter/transform results as needed
        .setBody(simple("insert into processed_customer values('${body[ID]}','${body[NAME]}')"))
        .to("jdbc:testdb");
Copy to Clipboard Toggle word wrap

その他の参考資料

トップに戻る
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2025 Red Hat