【问题标题】:A way to upsert multiple records together?一种将多个记录一起插入的方法?
【发布时间】:2022-01-16 16:10:38
【问题描述】:

我正在尝试看看是否有办法改进数据的插入和更新方式。

我正在使用带有 JDBC 的 ORACLE DB。

我目前的做法是在检查 toUpdate 是否为 true 之后使用 FOR 循环更新(例如)客户记录。一个示例,例如下面的示例代码,然后调用现有的 DAO update() 来执行此操作。但这不允许将多个数据合并在一起。

但是,有没有更好的方法将多个数据一起 UPSERT?

        if (toUpdate) {
            for (Customer customerRec : customerRecList) 
                customerRecDAO.update(customerRec);
        }

【问题讨论】:

标签: spring oracle java-8 spring-jdbc upsert


【解决方案1】:

是的,您可以使用批处理:

public <T> int saveInBatch(List<T> records, String sql, Function<T, MapSqlParameterSource> paramFn){

try{
MapSqlParameterSource[] params = records.stream().map(paramFn).toArray(MapSqlParameterSource[]::new);
int rowCount = jdbcTemplate.batchUpdate(sql, params);
return Arrays.stream(rowCount).sum();
}
catch(Exception e){
//exception handling 
}
}

paramFn 是一个 lambda 函数,您可以将记录映射到它们的值。示例可能是

(record)->{
return new MapSqlParameterSource("username" ,username),Integer.class);//just example
}

why we use MapSqlParameterSource

您可以通过传递较小批次或自定义批次记录的方式调用 saveInBatch。假设您有一百万条记录,那么您可能希望一次只更新 200-400 条记录,因此您可以执行以下操作:

private <T> int saveRecords(List<T> records, String sql, Function<T, MapSqlParameterSource> paramFn) throws Exception{

return Lists.partition(records, 300).stream().map(batch-> saveInBatch(batch, sql, paramFn)).mapToInt(Integer::intValue).sum();
}

上面的Note: 没有得到很好的优化,或者没有充分利用流,但这是我很久以前尝试过的有效代码:)。

【讨论】:

    猜你喜欢
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多