236.6. StatementType を使用して MyBatis をより適切に制御する

MyBatis エンドポイントにルーティングする場合、実行する SQL ステートメントが SELECTUPDATEDELETE または INSERT などであるかどうかを制御できるように、よりきめ細かい制御が必要になります。たとえば、IN ボディに SELECT ステートメントへのパラメーターが含まれている MyBatis エンドポイントにルーティングする場合は、次のようにします。

上記のコードでは、MyBatis ステートメントの selectAccountById を呼び出すことができます。IN 本文には、取得するアカウント ID (Integer 型など) が含まれている必要があります。

SelectList など、他のいくつかの操作についても同じことができます。

UPDATE についても同様で、Account オブジェクトを IN ボディとして MyBatis に送信できます。

236.6.1. InsertList StatementType の使用

Camel 2.10 以降で利用可能

MyBatis では、for-each バッチドライバーを使用して複数の行を挿入できます。これを使用するには、マッパー XML ファイルで <foreach> を使用する必要があります。たとえば、次のようになります。

次に、以下に示すように、InsertList ステートメントタイプを使用する mybatis エンドポイントに Camel メッセージを送信することにより、複数の行を挿入できます。

236.6.2. UpdateList StatementType の使用

Camel 2.11 から利用可能

MyBatis では、for-each バッチドライバーを使用して複数の行を更新できます。これを使用するには、マッパー XML ファイルで <foreach> を使用する必要があります。たとえば、次のようになります。

<update id="batchUpdateAccount" parameterType="java.util.Map">
    update ACCOUNT set
    ACC_EMAIL = #{emailAddress}
    where
    ACC_ID in
    <foreach item="Account" collection="list" open="(" close=")" separator=",">
        #{Account.id}
    </foreach>
</update>

次に、以下に示すように、UpdateList ステートメントタイプを使用する mybatis エンドポイントに Camel メッセージを送信することにより、複数の行を更新できます。

from("direct:start")
    .to("mybatis:batchUpdateAccount?statementType=UpdateList")
    .to("mock:result");

236.6.3. DeleteList StatementType の使用

Camel 2.11 から利用可能

MyBatis では、for-each バッチドライバーを使用して複数の行を削除できます。これを使用するには、マッパー XML ファイルで <foreach> を使用する必要があります。たとえば、次のようになります。

<delete id="batchDeleteAccountById" parameterType="java.util.List">
    delete from ACCOUNT
    where
    ACC_ID in
    <foreach item="AccountID" collection="list" open="(" close=")" separator=",">
        #{AccountID}
    </foreach>
</delete>

次に、以下に示すように、DeleteList ステートメントタイプを使用する mybatis エンドポイントに Camel メッセージを送信することにより、複数の行を削除できます。

from("direct:start")
    .to("mybatis:batchDeleteAccount?statementType=DeleteList")
    .to("mock:result");

236.6.4. InsertList、UpdateList、および DeleteList StatementTypes に関する通知

任意のタイプ (List、Map など) のパラメーターを mybatis に渡すことができ、エンドユーザーは mybatis 動的クエリー 機能の助けを借りて、必要に応じてそれを処理する責任があります

236.6.5. スケジュールされたポーリングの例

このコンポーネントはスケジュールされたポーリングをサポートしているため、ポーリングコンシューマーとして使用できます。たとえば、毎分データベースをポーリングするには:

from("mybatis:selectAllAccounts?delay=60000").to("activemq:queue:allAccounts");

その他のオプションについては、Polling Consumer の ScheduledPollConsumer オプションを参照してください。

あるいは、TimerQuartz コンポーネントなど、スケジュールされたポーリングをトリガーする別のメカニズムを使用することもできます。 以下のサンプルでは、Timer コンポーネントを使用して 30 秒ごとにデータベースをポーリングし、データを JMS キューに送信します。

from("timer://pollTheDatabase?delay=30000").to("mybatis:selectAllAccounts").to("activemq:queue:allAccounts");

そして、使用される MyBatis SQL マッピングファイル:

  <!-- Select with no parameters using the result map for Account class. -->
  <select id="selectAllAccounts" resultMap="AccountResult">
    select * from ACCOUNT
  </select>

236.6.6. onConsume の使用

このコンポーネントは、データが Camel によって消費および処理された 後の ステートメントの実行をサポートします。これにより、データベースでポスト更新を行うことができます。すべてのステートメントは UPDATE ステートメントでなければならないことに注意してください。Camel は、名前をコンマで区切る必要がある複数のステートメントの実行をサポートしています。

以下のルートは、consumeAccount ステートメントを実行してデータが処理されることを示しています。これにより、データベース内の行のステータスを処理済みに変更できるため、2 回以上消費することを回避できます。

そして、sqlmap ファイル内のステートメント:

236.6.7. トランザクションへの参加

camel-mybatis の下でトランザクションマネージャーをセットアップするのは、標準の MyBatis SqlMapConfig.xml ファイルの外部にデータベース設定を外部化する必要があるため、少し手間がかかる場合があります。

最初の部分では、DataSource のセットアップが必要です。これは通常、Spring プロキシーでラップする必要があるプール (DBCP または c3p0) です。このプロキシーにより、Spring 以外での DataSource の使用が Spring トランザクションに参加できるようになります (MyBatis SqlSessionFactory はまさにこれを行います)。

    <bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <constructor-arg>
            <bean class="com.mchange.v2.c3p0.ComboPooledDataSource">
                <property name="driverClass" value="org.postgresql.Driver"/>
                <property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/myDatabase"/>
                <property name="user" value="myUser"/>
                <property name="password" value="myPassword"/>
            </bean>
        </constructor-arg>
    </bean>

これには、プロパティープレースホルダーを使用してデータベース設定を外部化できるという追加の利点があります。

次に、最も外側の DataSource を管理するようにトランザクションマネージャーを設定します。

    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

mybatis-spring SqlSessionFactoryBean は、同じ DataSource をラップします。

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- standard mybatis config file -->
    <property name="configLocation" value="/META-INF/SqlMapConfig.xml"/>
        <!-- externalised mappers -->
    <property name="mapperLocations" value="classpath*:META-INF/mappers/**/*.xml"/>
    </bean>

camel-mybatis コンポーネントは、そのファクトリーで設定されます。

    <bean id="mybatis" class="org.apache.camel.component.mybatis.MyBatisComponent">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

最後に、トランザクションマネージャーの上にトランザクションポリシーが定義され、通常どおり使用できます。

    <bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="txManager"/>
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
    </bean>

    <camelContext id="my-model-context" xmlns="http://camel.apache.org/schema/spring">
        <route id="insertModel">
            <from uri="direct:insert"/>
            <transacted ref="PROPAGATION_REQUIRED"/>
            <to uri="mybatis:myModel.insert?statementType=Insert"/>
        </route>
    </camelContext>