89.9. 使用声明Type 来更好地控制 MyBatis
当路由到 MyBatis 端点时,您需要更精细的控制,以便您可以控制要执行的 SQL 语句是 SELECT、UPDATE、DELETE 或 INSERT 等。因此,如果我们想路由到一个 MyBatis 端点,IN 正文包含参数到 SELECT 语句中,我们可以进行:
在上面的代码中,我们可以调用 MyBatis 语句 selectAccountById,IN 正文应包含要检索的帐户 ID,如 Integer 类型。
对于某些其他操作,您可以执行相同的操作,如 SelectList :
和 UPDATE 相同,您可以在其中将 Account 对象作为 IN 正文发送到 MyBatis :
89.9.1. 使用 InsertList 语句Type 复制链接链接已复制到粘贴板!
MyBatis 允许您使用其 for-each batch 驱动程序插入多行。要使用它,您需要在 mapper XML 文件中使用 <foreach>。例如,如下所示:
然后,您可以通过向使用 InsertList 语句类型的 mybatis 端点发送 Camel 消息来插入多行,如下所示:
89.9.2. 使用 UpdateList 语句Type 复制链接链接已复制到粘贴板!
MyBatis 允许您使用其 for-each batch 驱动程序更新多行。要使用它,您需要在 mapper 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");
89.9.3. 使用 DeleteList 语句Type 复制链接链接已复制到粘贴板!
MyBatis 允许您使用其 for-each batch 驱动程序删除多行。要使用它,您需要在 mapper 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");
任何类型(List、映射等)的参数可以传递给 mybatis,最终用户负责根据需要处理它
,并帮助 mybatis 动态查询 功能。
89.9.5. cheduled 轮询示例 复制链接链接已复制到粘贴板!
这个组件支持调度的轮询,因此可用作 Polling Consumer。例如,每分钟轮询数据库:
from("mybatis:selectAllAccounts?delay=60000")
.to("activemq:queue:allAccounts");
如需了解更多选项,请参阅 Polling Consumer 上的 "ScheduledPollConsumer Options"。
或者,您可以使用另一个机制来触发调度的轮询,如 Timer 或 Quartz 组件。在以下示例中,我们轮询数据库,每 30 秒使用 Timer 组件并将数据发送到 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>
89.9.6. 使用 onConsume 复制链接链接已复制到粘贴板!
此组件支持在 Camel 消耗和处理数据 后执行 语句。这可让您在数据库中进行发布更新。请注意,所有语句都必须是 UPDATE 语句。Camel 支持执行多个名称应用逗号分开的语句。
以下路由说明了执行 consumeAccount 语句数据已被处理。这样,我们可以将数据库中的行的状态更改为处理,因此我们避免消耗两次或更多。
和 sqlmap 文件中的语句:
89.9.7. 参与事务 复制链接链接已复制到粘贴板!
在 camel-mybatis 下设置事务管理器可能稍微小,因为它涉及在标准 MyBatis SqlMapConfig.xml 文件外部化数据库配置。
第一部分需要设置 DataSource。这通常是一个池(DBCP 或 c3p0),它需要嵌套在 Spring 代理中。此代理启用了 DataSource 的非 Spring 使用来参与 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>
这具有额外的好处,使数据库配置能够使用属性占位符进行外部化。
然后,将事务管理器配置为管理 外部数据源 :
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
mybatis-springSqlSessionFactoryBean,然后换行同一 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>