JdbcTemplate 批处理更新问题

Posted

技术标签:

【中文标题】JdbcTemplate 批处理更新问题【英文标题】:Issue with JdbcTemplate batchUpdate 【发布时间】:2021-06-20 15:08:02 【问题描述】:

有一个简单的要求,我必须对更新查询的对象列表执行批处理更新。

问题是运行代码后,在数据库表中,我只看到第一行得到更新,其余行没有得到更新。下面是我为此使用的示例代码。

公共无效更新(列表列表)

    String sql = "UPDATE table1 \\\r\n"
            + "SET col1 = ?, col2 = ?, modified_on = UTC_TIMESTAMP() \\\r\n"
            + "WHERE col3 = ? \\\r\n"
            + "AND col4 = ? \\\r\n"
            + "AND col5 = ? \\\r\n"
            + "AND col6 = ?" // col5 will be different for different records.

        int[] rowsArray = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() 
            
            
            @Override
            public int getBatchSize() 
                return list.size();
            
            @Override
            public void setValues(PreparedStatement ps, int index) throws SQLException 
                SampleClass sampleClass = list.get(index);
                
                ps.setString(1, sampleClass.getCol1());
                ps.setString(2, sampleClass.getCol2());
                ps.setString(3, sampleClass.getCol3());
                ps.setString(4, sampleClass.getCol4());
                ps.setString(5, sampleClass.getCol5());
                ps.setString(6, sampleClass.getCol6());
                
                
            
        );

如果我的列表大小为 N,我什至可以确认 setValues() 方法确实会执行 N 次。但仍然会执行 batchUpdate,在 DB 中仅更新第一行。我什至尝试更改列表中的对象序列,结果仍然相同。但是,如果我在循环内对 N 大小列表运行 JdbcTemplate.update() 方法 N 次,则 N 记录会在 DB 中更新,但不会使用 JdbcTemplate.batchUpdat()。我什至也尝试了 NamedParameterJdbcTemplate 的解决方案,但仍然是同样的问题。此外,我在同一个数据库中的其他表中执行批处理更新的逻辑相同,并且此操作在相同的代码流中编码。一切都很好。

关于为什么只更新第一条记录的任何帮助?

【问题讨论】:

每条记录都必须添加到最终批次中。那是您的代码中缺少的。添加ps.addBatch() 将解决您的问题 【参考方案1】:

每条记录都必须添加到最终批次中。您的代码中缺少该内容。添加ps.addBatch() 将解决您的问题

String sql = "UPDATE table1 \\\r\n"
        + "SET col1 = ?, col2 = ?, modified_on = UTC_TIMESTAMP() \\\r\n"
        + "WHERE col3 = ? \\\r\n"
        + "AND col4 = ? \\\r\n"
        + "AND col5 = ? \\\r\n"
        + "AND col6 = ?" // col5 will be different for different records.

    int[] rowsArray = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() 
        
        
        @Override
        public int getBatchSize() 
            return list.size();
        
        @Override
        public void setValues(PreparedStatement ps, int index) throws SQLException 
            SampleClass sampleClass = list.get(index);
            
            ps.setString(1, sampleClass.getCol1());
            ps.setString(2, sampleClass.getCol2());
            ps.setString(3, sampleClass.getCol3());
            ps.setString(4, sampleClass.getCol4());
            ps.setString(5, sampleClass.getCol5());
            ps.setString(6, sampleClass.getCol6());
            
            ps.addBatch(); // Add this
        
    );

【讨论】:

以上是关于JdbcTemplate 批处理更新问题的主要内容,如果未能解决你的问题,请参考以下文章

JdbcTemplate 批处理更新问题

spring 如何获取 jdbctemplate

使用MockIto模拟声明

Spring JdbcTemplate.batchUpdate()

DAO 构造函数中 JDBC 模板的 NullPointerException

jdbcTemplate 更新后如何刷新 entityManager 状态