如何使用 jooq 进行批量插入而不获取序列号。

huangapple go评论73阅读模式
英文:

How to batch insert using jooq without fetching sequence number

问题

我想使用 jooq 对 PostgreSQL 进行批量插入:

List<MyTableRecord> records = new ArrayList<>();
for (Dto dto : dtos) {
    Field<Long> sequenceId = SEQUENCE.nextval();
    Long id = using(ctx).select(sequenceId).fetchOne(sequenceId);
    records.add(mapToRecord(dto, id));
}
using(ctx).batchInsert(records).execute();

问题是我为每一行获取下一个序列号。

对于简单的插入,我可以在语句中使用类似这样的 Field

create.insertInto(ID, VALUE)
  .values(SEQUENCE.nextval(), val("William"))
  .execute();

在批量插入中如何做到这一点呢?

英文:

I want to do batch insert to postgres using jooq:

List&lt;MyTableRecord&gt; records = new ArrayList&lt;&gt;();
for (Dto dto : dtos) {
    Field&lt;Long&gt; sequenceId = SEQUENCE.nextval();
    Long id = using(ctx).select(sequenceId).fetchOne(sequenceId);
    records.add(mapToRecord(dto, id));
}
using(ctx).batchInsert(records).execute();

The problem is that I am fetching next sequence number for each row.

For simple insert I can use Field<Long> in statement like this:

create.insertInto(ID, VALUE)
  .values(SEQUENCE.nextval(), val(&quot;William&quot;))
  .execute();

How can I do so with batch insert?

答案1

得分: 1

预提取所有序列值

您可以使用以下方法预提取所需的所有序列值:

List<Long> ids = using(ctx)
    .select(sequenceId)
    .from(generateSeries(1, dtos.size()))
    .fetch(sequenceId);

for (int i = 0; i < dtos.size(); i++)
    records.add(mapToRecord(dtos.get(i), ids.get(i)));

using(ctx).batchInsert(records).execute();

这似乎是一个有用的功能,在 RDBMS 不可知的情况下通过 using(ctx).nextvals(SEQUENCE, dtos.size()) 进行操作。我们将在未来的 jOOQ 版本中考虑这一点:https://github.com/jOOQ/jOOQ/issues/10658

不要使用记录

另一种方法是批量执行实际的 INSERT 语句,而不是通过 Record.insert() 调用来进行操作,可以通过 batchInsert() 实现。这样,您可以将 SEQUENCE.nextval() 表达式放入语句中。详情请参阅:https://www.jooq.org/doc/latest/manual/sql-execution/batch-execution/

英文:

Pre-fetch all the sequence values

You could pre-fetch all the sequence values you need using this:

List&lt;Long&gt; ids = using(ctx)
    .select(sequenceId)
    .from(generateSeries(1, dtos.size()))
    .fetch(sequenceId);

for (int i = 0; i &lt; dtos.size(); i++)
    records.add(mapToRecord(dtos.get(i), ids.get(i)));

using(ctx).batchInsert(records).execute();

This seems like a useful feature to have out of the box, in an RDBMS agnostic way via using(ctx).nextvals(SEQUENCE, dtos.size()). We'll consider this for a future jOOQ version: https://github.com/jOOQ/jOOQ/issues/10658

Don't use records

An alternative is to batch actual INSERT statements instead of Record.insert() calls via batchInsert(). That way, you can put the SEQUENCE.nextval() expression in the statement. See: https://www.jooq.org/doc/latest/manual/sql-execution/batch-execution/

huangapple
  • 本文由 发表于 2020年9月18日 19:35:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63955003.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定