一种将多个记录一起插入的方法?
Posted
技术标签:
【中文标题】一种将多个记录一起插入的方法?【英文标题】: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 JDBC模板吗? 在 Spring-boot 中使用 spring data jpa 我们有 saveAll()。如果spring JDBC通过tutorialspoint.com/spring/spring_jdbc_example.htm 【参考方案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:
没有得到很好的优化,或者没有充分利用流,但这是我很久以前尝试过的有效代码:)。
【讨论】:
以上是关于一种将多个记录一起插入的方法?的主要内容,如果未能解决你的问题,请参考以下文章
寻找一种将 select2 控件与 tablesorter 的内部过滤器小部件一起使用的方法
laravel 在插入之前检查记录是不是存在,这是一种有效的方法
在不使用 jquery/ajax 的情况下自动将新记录插入到表中时,使用新记录更新页面的另一种方法是啥