英文:
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<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();
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("William"))
.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<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();
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/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论