使用 Mybatis 3.4.6 进行 Oracle 批量更新并获得“-1”结果

Using Mybatis 3.4.6 for Oracle Batch-Update and Got the "-1" result

我的代码是这样的:

<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 时得到 false 结果 我试过 application.yml 这样的:

mybatis:
    configuration:
        default-executor-type: simple

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

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

映射器语句包含纯 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() returns 列表 BatchResult。在这种情况下,批处理中只有一条语句,因此列表大小为 1。如果执行多条语句(例如更新 table A,然后插入 table B),则列表可能包含多个 BatchResults.
  • BatchResult#getUpdateCounts() returns 一个整型数组。第一个元素 (=int) 是第一个 UPDATE 更新的行数,第二个元素是第二个 UPDATE 更新的行数,依此类推。
  • 如果要更新很多行,则应间歇性地刷新语句。请参阅 了解如何控制批量大小。