【问题标题】:How to make batch insert in Oracle Database如何在 Oracle 数据库中进行批量插入
【发布时间】:2019-03-28 15:11:41
【问题描述】:

我需要将批量插入到 Oracle 数据库中,但我对如何进行批量操作感到困惑。

String INSERT = "INSERT INTO LOGS(METHOD,USER,START_DATE,RESPONSE_TIME,IS_ERROR) VALUES (?,?,?,?,?)";

private synchronized void saveToDBAndClear(ConcurrentHashMap<Long, Logs> logs) {
    List<Logs> list = new ArrayList<>(logs.values());
    logService.insertLog(list);
    initLogMap();
}


    public void insertLog(List<Logs> logsList) {

        int[] insertedLog = jdbcTemplate.batchUpdate(INSERT, new BatchPreparedStatementSetter() {

            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ps.setString(1, logsList.get(i).getMethod());
                ps.setString(2, logsList.get(i).getUser());
                ps.setTimestamp(3, logsList.get(i).getStartDate());
                ps.setLong(4, logsList.get(i).getResponseTime());
                ps.setString(5, logsList.get(i).getIsError());
            }

            @Override
            public int getBatchSize() {
                return logsList.size();
            }
        });
        logger.info("It was inserted {} logs into Logs", insertedLog.length);
    }

我必须这样做

List<Logs> list = new ArrayList<>(logs.values());

因为我不知道怎么用jdbcTemplate.batchUpdate()

对于每个ConcurrentHashMap 并收集 100 或 1000 卷中的批次以推送到数据库中。

有人可以帮我吗?

附言

我试过了

public class LogProcessor {
private int batchSize = 10;
private final double initialCapacity = 1.26;
private ConcurrentHashMap<Long, Logs> logMap;
private AtomicLong logMapSize;

    private void initLogMap() {
this.logMap = new ConcurrentHashMap<>((int) (batchSize * initialCapacity));
this.logMapSize = new AtomicLong();
    }

public void process(LogKeeper keeper){
 LogHandler log = keeper.getLog();
 Long i = logMapSize.incrementAndGet();
 logMap.put(i, log.toJdbc());
 System.out.println("Lines inside the map = "+logMap.size());
 if (i % batchSize == 0) {
  System.out.println("Reached batchSize and = " + batchSize);
                    saveToDBAndClear(logMap);
                }

private synchronized void saveToDBAndClear(ConcurrentHashMap<Long, Logs> logs) {
List<Logs> list = new ArrayList<>(logs.values());
System.out.println("Created list with size = "+ list.size());
logService.insertLog(list);
initLogMap();
System.out.println("Now size of map = "+ logs.size()+" and AtomicLong = "+logMapSize.intValue() );
}

    @TransactionalRollback
    public void insertLog(List<Logs> logsList) {
        System.out.println("Inside insertLog method");
        int[][] insertedLog=jdbcTemplate.batchUpdate(INSERT, logsList, 15, (ps, arg) -> {
            ps.setString(1, arg.getMethod());
            ps.setString(2, arg.getClient());
            ps.setTimestamp(3, arg.getStartDate());
            ps.setLong(4, arg.getResponseTime());
            ps.setString(5, arg.getIsError());
        });
        System.out.println("It was inserted " + insertedLog[0].length + " logs into DB");
    }
}

现在,如您所见。我作为私有字段的 batchSize 是 10。在 batchUpdate 中,我输入了 15。我想,如果我发送到 insertLog 方法列表,例如大小等于 1 或 100,它将收集到大小等于 15 的批次并将发送到DB,但只插入列表包含的那个卷。

因此,我必须在我的 Map 中准确收集我需要的 batchSize,然后将其发送到 insertLog 方法。如果可以的话,我只会将 Logs 日志发送到 insertLog 方法并放入类似

的内容
 public void insertLog(Logs logs){
jdbcTemplate.batchUpdate(INSERT, logs, 1000, (ps, arg) ->(...));}

在那之后有人可以帮助那个bathSize插入吗?是否可以在没有像 10%batchSize=0 这样的简单验证的情况下进行 batchInsert 或 batchUpdate ?

【问题讨论】:

  • 如果您要问如何以 1000 个为单位执行更新,您是否考虑过使用 batchUpdate(java.lang.String sql, java.util.Collection&lt;T&gt; batchArgs, int batchSize, ParameterizedPreparedStatementSetter&lt;T&gt; pss) 重载?
  • @Andreas 如果我找到了correct 那么这不是我要找的。我尝试public void insertLog(List&lt;Logs&gt; logsList) { jdbcTemplate.batchUpdate(INSERT, list, 15, (ps,arg)-&gt;{ ps.setString(1, arg.getMethod()); ps.setString(2, arg.getClient()); } }); 它插入了 10 个,再插入 10 个,再插入 10 个元素,它们在列表中,而不是像我想的那样收集 15 行。无论如何,我不能插入到 batchUpdate 我的对象中,我必须在那里插入任何 Collection
  • 你怎么知道它一次插入 10 个,而不是 15 个? --- 鉴于它不应该“收集”任何东西,你所说的 “不收集 15 行”是什么意思? --- 你说的“我不能插入batchUpdate我的对象,我必须插入任何集合”是什么意思?您的代码使用集合 (logsList)。新代码可以直接使用logs.values(),而无需先转换为List,但其他方面相同。
  • 关于转换为列表,ure correct. ---_How do you know it insert 10 at a time, not 15?_ I have logger.info(...) about it, and I see, that it was inserted 10 rows, but not 15. Now, I collect batch in Map, till the count of logs less than 100 like logs%100=0` 但我想在 Oracle 级别制作 batchUpdate(....logs.value, 100) 并在该方法中,或者jdbc 或 jpa,它应该在内存中收集我的值(行),当它达到 100 时,它将发送到 DB
  • 仍然不知道你在说什么“收集”任何东西。您已经在logsList 中收集您需要的一切。然后,您使用该列表调用 batchUpdate 的 4 参数版本,要求它一次批量更新 15 个。编辑问题并显示您尝试过的代码,并包括(子集)创建的日志,显示它一次只批处理 10 个,因为我看不出这是怎么发生的,因为您没有收到通知它执行一个批处理,但由于我看不到你做了什么,所以很难说。

标签: java spring oracle jdbc


【解决方案1】:

看看PLSQLSample.java 供参考

【讨论】:

  • 是的,它看起来不错,但是 Its not that Im 正在寻找,因为我有由 Spring 实现的 jdbc 连接,但我没有找到适合我的情况的任何好的变体。跨度>
猜你喜欢
  • 2015-06-17
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 2014-08-30
  • 1970-01-01
  • 1970-01-01
  • 2011-07-28
相关资源
最近更新 更多