102.9. 使用 statementType 来更好地控制 MyBatis
当路由到 MyBatis 端点时,您需要更为精细的控制,以便您可以控制要执行的 SQL 语句是否为 SELECT
、UPDATE
、DELETE
或 INSERT
等。例如,如果我们希望路由到一个 MyBatis 端点,则 IN 正文包含参数到 SELECT
语句,我们可以执行以下操作:
在上面的代码中,我们可以调用 MyBatis 语句 selectAccountById
,而 IN 正文应包含您要检索的帐户 ID,如 Integer
类型。
对于某些其他操作,您可以执行相同的操作,如 SelectList
:
和 UPDATE
相同,您可以在其中将 帐户
对象作为 IN 正文发送到 MyBatis :
102.9.1. 使用 InsertList StatementType
MyBatis 允许您使用其 for-each batch 驱动程序插入多行。要使用它,您需要在映射器 XML 文件中使用 <foreach>。例如:
然后,您可以通过向使用 InsertList
语句类型的 mybatis
端点发送 Camel 消息来插入多行,如下所示:
102.9.2. 使用 UpdateList StatementType
MyBatis 允许您使用其 for-each batch 驱动程序更新多行。要使用它,您需要在映射器 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");
102.9.3. 使用 DeleteList StatementType
MyBatis 允许您使用其 for-each batch 驱动程序删除多行。要使用它,您需要在映射器 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");
102.9.4. 注意 InsertList、UpdateList 和 DeleteList StatementTypes
任何类型(List、Map 等)的参数都可以传递给 mybatis,最终用户负责处理它
,以帮助 mybatis 动态查询 功能。
102.9.5. 受推的轮询示例
此组件支持调度的轮询,因此可用作 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>
102.9.6. 使用 onConsume
此组件支持在 Camel 使用和处理数据 后执行 声明。这可让您在数据库中进行升级后的更新。注意所有语句都必须是 UPDATE
语句。Camel 支持执行多个语句,其名称应该用逗号分开。
以下路由演示了我们执行 consumeAccount 语句数据。这样,我们可以将数据库中行的状态更改为处理,因此我们避免消耗两次。
和 sqlmap 文件中的语句:
102.9.7. 参与事务
在 camel-mybatis 下设置事务管理器可能会很有点,因为它涉及将数据库配置外部化到标准 MyBatis SqlMapConfig.xml
文件外。
第一部分要求设置 数据源
。这通常是池(DBCP 或 c3p0),后者需要嵌套在 Spring 代理中。此代理可让 DataSource 的非 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>