【问题标题】:Insert Arraylist in Database in Mule在 Mule 的数据库中插入 Arraylist
【发布时间】:2019-06-23 22:39:01
【问题描述】:

我正在尝试使用 Mule ESB 将 ArrayList 的内容插入到 SQL Server 数据库中。 ArrayList 看起来像

[
    {Id=a1o90000001muvWAAQ, Billing_Number__c=1000005, type=Call_Log__c}, 
    {Id=a1o90000001muvXAAQ, Billing_Number__c=1000006, type=Call_Log__c}
]

我应该如何以优化的方式将它插入到数据库中?

我的骡子流程如下。

<sfdc:query config-ref="Salesforce__Basic_authentication" query="#[flowVars.query]" 
        doc:name="Salesforce"/>
<set-variable variableName="result" value="#[new java.util.ArrayList()]" 
        doc:name="Variable"/>
<foreach doc:name="For Each">
    <set-variable variableName="itrresult" value="#result.add(message.payload)]" 
            doc:name="Variable"/>
</foreach>
<splitter expression="#[flowVars.result]" doc:name="Splitter"/>
<logger message="#[payload['Id']]" level="INFO" doc:name="Logger"/>

#[payload['Id']] 在日志中为我提供了 Id LoggerMessageProcessor: a1o90000001mzgzAAA。

我不确定我在做什么是正确的。我在 Mule 的学习曲线刚刚起步。

【问题讨论】:

  • 记录 ID 是一项要求吗?或者你只是为了调试目的?
  • @ericbn 你是对的。我这样做是为了调试。实际需求是插入到SQL db中

标签: arraylist mule esb


【解决方案1】:

您不需要拆分器或 Foreach 范围。数据库连接器有一个bulk mode,它使连接器接受一个集合作为有效负载。

允许通过一个查询提交数据集合,[...]。启用批量模式可提高应用程序的性能,因为它减少了单个查询执行的次数。批量模式要求参数化查询至少包含一个参数。

在插入、更新或删除操作中使用bulkMode="true" 启用它。

编辑:在您的 Salesforce 查询组件之后使用它:

    <sfdc:query config-ref="" query="#[flowVars.query]" doc:name="Salesforce"/>
    <db:insert config-ref="" bulkMode="true" doc:name="Database">
        <db:parameterized-query>
            <![CDATA[INSERT INTO TABLE (ID, BILLING_NUMBER__C, TYPE)  
            VALUES (#[payload.Id], #[payload.Billing_Number__c], #[payload.type]);]]>
        </db:parameterized-query>
    </db:insert>

Database Insert 组件返回的有效负载是一个数组,其中每个执行的查询都会更改行数。在您的情况下,一个数组,其大小与 Salesforce 查询组件返回的项目数相同,例如 [1, 1, 1, ...]

如果您仍需要登录,请执行以下操作:

    <sfdc:query config-ref="" query="#[flowVars.query]" doc:name="Salesforce"/>
    <foreach doc:name="For Each">
       <logger message="#[payload.Id]" level="INFO" doc:name="Logger"/>
    </foreach>
    <db:insert config-ref="" bulkMode="true" doc:name="Database">
        <db:parameterized-query><!-- the query --></db:parameterized-query>
    </db:insert>

或者这个:

    <sfdc:query config-ref="" query="#[flowVars.query]" doc:name="Salesforce"/>
    <foreach doc:name="For Each">
       <logger message="#[payload.Id]" level="INFO" doc:name="Logger"/>
        <db:insert config-ref="" doc:name="Database"><!-- bulkMode disabled -->
            <db:parameterized-query><!-- the query --></db:parameterized-query>
        </db:insert>
    </foreach>

【讨论】:

  • 感谢@ericbn - 但是如果我尝试像您提到的那样访问数组列表#[payload.Id]。我只看到空值。
  • 你的 ArrayList 里面有什么? HashMap 的实例?数据库组件将迭代您的每个实例,因此如果 #[payload[0].Id] 在组件接收的有效负载中有效,则 #[payload.Id] 在查询中有效。
  • 我不确定是否需要查询末尾的;。可能是。如果您遇到问题,请尝试添加它。
  • 我迫不及待地想测试一下并回复你——这是我最早可以再次登录 mule 的时间。实际上,我正在查询 Salesforce,所以我得到的有效负载是消费者迭代器,我将其转换为数组列表,然后将其拆分并在 Insert DB 语句中使用。如果我尝试不拆分数组列表并使用#[payload[0].Id],我会收到如下错误消息表达式“payload[0].Id”的执行失败。 (org.mule.api.expression.ExpressionRuntimeException)。消息负载的类型:ConsumerIterator
  • @Anandmagesh,您能否更新您的问题,发布您拥有的此流程的代码?
【解决方案2】:

使用拆分器拆分您的数组并单独插入:

    <splitter expression="#[payload]" />
    <db:insert config-ref="Config" doc:name="Database">
        <db:parameterized-query><![CDATA[insert into xx(Id, Billing_Number__c, type) values('#[payload['Id']]','#[payload['Billing_Number__c']]','#[payload['type']]');]]></db:parameterized-query>
    </db:insert>

【讨论】:

  • 那么插入操作将作为一次性操作执行,或者对于每个拆分器值插入将单独发生?如果我在批量提交中使用它怎么办?
  • 拆分器会将您的消息拆分为多条消息,每条消息都有一个数组项的有效负载。所有将并行执行。
【解决方案3】:

您可以使用for 遍历ArrayList,使用db:dynamic-query 逐一插入值。

【讨论】:

    【解决方案4】:

    Mule 支持批量模式插入数据集合。我更喜欢 SQL 语句中带有标签的 db:in-param 元素。配置已使用 Mule 3.8.5 进行测试。

    <db:insert config-ref="databaseConfiguration" bulkMode="true" doc:name="Database">
        <db:parameterized-query>
        <![CDATA[INSERT INTO T_ORDER (ORDER_NO,CUSTOMER_NO) VALUES (:orderNo, :customerNo)]]>
        </db:parameterized-query>
        <db:in-param name="orderNo"  value="#[payload.orderNo]" />
        <db:in-param name="customerNo"  value="#[payload.customerNo]" />
    </db:insert>
    

    批量模式提供了更好的性能。确保您的 DBMS 已针对此用例正确配置。

    在调用db:insert 组件之前,可以对包含大量条目的集合进行分区,例如分成 100 个条目的子集合。

    <!-- Sample: Collection with 1.000 entries -->
    <!-- will be chunked into sub collections with 100 entries -->
    <foreach batchSize="100" />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      相关资源
      最近更新 更多