【问题标题】:Using Mybatis 3.4.6 for Oracle Batch-Update and Got the "-1" result使用Mybatis 3.4.6 for Oracle Batch-Update 得到“-1”结果
【发布时间】:2020-03-13 13:02:36
【问题描述】:

我的代码是这样的:

<update id="biz-update" parameterType="java.util.List">
    <foreach collection="list" index="index" item="item" open="begin" close=";end;" separator=";">
        update
        biz_tbl
        <set>
            freeze_amount = nvl(freeze_amount,0) + #{item.payAmount}
        </set>
        where
        id = #{item.cardId}
    </foreach>
</update>

而且我在使用 Integer 时总是得到 -1 结果,或者在使用 Boolean 时得到错误结果 我试过application.yml这样:

mybatis:
    configuration:
        default-executor-type: simple

好像没关系。 那么,如何才能得到正确的 oracle 批量更新结果呢?

【问题讨论】:

  • 您必须升级到 Oracle 12 或更高版本 - 请参阅类似的答案 here

标签: oracle mybatis


【解决方案1】:

这不是批处理操作。
它试图通过单个 PreparedStatement#execute() 调用执行多个语句而 Oracle 的 JDBC 驱动程序不支持它(更正:驱动程序支持它)。
正确的方法是执行 real 批处理操作。

mapper 语句包含一个普通的 UPDATE 语句。

<update id="biz-update">
  update biz_tbl
  set freeze_amount = nvl(freeze_amount,0) + #{payAmount}
  where id = #{cardId}
</update>

以下代码执行批处理操作。

SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
  for (YourItem item : list) {
    sqlSession.update("biz-update", item);
  }
  List<BatchResult> results = sqlSession.flushStatements();
  int totalNumberOfAffectedRows = Arrays.stream(results.get(0).getUpdateCounts()).sum();
  sqlSession.commit();
} finally {
  sqlSession.close();
}
  • sqlSession#flushStatements() 返回BatchResult 的列表。在这种情况下,批处理中只有一条语句,因此列表大小为1。如果执行多条语句(例如更新表A,然后插入表B),列表可能包含多个BatchResults。李>
  • BatchResult#getUpdateCounts() 返回一个 int 数组。第一个元素 (=int) 是第一个 UPDATE 更新的行数,第二个元素是第二个 UPDATE 更新的行数,依此类推。
  • 如果要更新许多行,则应间歇性地刷新语句。请参阅this answer 了解如何控制批量大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多