如何在 r2dbc 中批量执行多个插入?
How to execute multiple inserts in batch in r2dbc?
我需要批量将多行插入到一个 table 中。
在 DatabaseClient 中,我找到了 insert() 语句和 using(Publisher objectToInsert) 方法,该方法具有多个对象作为参数。但是它会不会一批插入它们?
另一个可能的解决方案是 connection.createBatch(),但它有一个缺点:我不能在那里传递我的实体对象,我不能从实体生成 sql 查询。
那么,是否可以在 r2dbc 中创建批量插入?
有两个问题:
Would DatabaseClient.insert()
insert them in one batch or not?
不是一批。
Is it possible to create batch insert in r2dbc? (except Connection.createBatch()
)
不,使用 Connection.createBatch()
只是为 现在.
创建 Batch
的一种方法
另见问题:
到现在还没有直接的支持,但是我发现可以用Connection
来简单地克服这个障碍,看看这个问题,spring-data-r2dbc#259
statement
有一个add
重复绑定参数。
我的解决方案的完整代码可以找到here。
return this.databaseClient.inConnectionMany(connection -> {
var statement = connection.createStatement("INSERT INTO posts (title, content) VALUES (, )")
.returnGeneratedValues("id");
for (var p : data) {
statement.bind(0, p.getTitle()).bind(1, p.getContent()).add();
}
return Flux.from(statement.execute()).flatMap(result -> result.map((row, rowMetadata) -> row.get("id", UUID.class)));
});
对该方法的测试。
@Test
public void testSaveAll() {
var data = Post.builder().title("test").content("content").build();
var data1 = Post.builder().title("test1").content("content1").build();
var result = posts.saveAll(List.of(data, data1)).log("[Generated result]")
.doOnNext(id->log.info("generated id: {}", id));
assertThat(result).isNotNull();
result.as(StepVerifier::create)
.expectNextCount(2)
.verifyComplete();
}
生成的 ID 按预期打印在控制台中。
...
2020-10-08 11:29:19,662 INFO [reactor-tcp-nio-2] reactor.util.Loggers$Slf4JLogger:274 onNext(a3105647-a4bc-4986-9ad4-1e6de901449f)
2020-10-08 11:29:19,664 INFO [reactor-tcp-nio-2] com.example.demo.PostRepositoryTest:31 generated id: a3105647-a4bc-4986-9ad4-1e6de901449f
//.....
2020-10-08 11:29:19,671 INFO [reactor-tcp-nio-2] reactor.util.Loggers$Slf4JLogger:274 onNext(a611d766-f983-4c8e-9dc9-fc78775911e5)
2020-10-08 11:29:19,671 INFO [reactor-tcp-nio-2] com.example.demo.PostRepositoryTest:31 generated id: a611d766-f983-4c8e-9dc9-fc78775911e5
//......
Process finished with exit code 0
我需要批量将多行插入到一个 table 中。 在 DatabaseClient 中,我找到了 insert() 语句和 using(Publisher objectToInsert) 方法,该方法具有多个对象作为参数。但是它会不会一批插入它们? 另一个可能的解决方案是 connection.createBatch(),但它有一个缺点:我不能在那里传递我的实体对象,我不能从实体生成 sql 查询。
那么,是否可以在 r2dbc 中创建批量插入?
有两个问题:
Would
DatabaseClient.insert()
insert them in one batch or not?
不是一批。
Is it possible to create batch insert in r2dbc? (except
Connection.createBatch()
)
不,使用 Connection.createBatch()
只是为 现在.
Batch
的一种方法
另见问题:
到现在还没有直接的支持,但是我发现可以用Connection
来简单地克服这个障碍,看看这个问题,spring-data-r2dbc#259
statement
有一个add
重复绑定参数。
我的解决方案的完整代码可以找到here。
return this.databaseClient.inConnectionMany(connection -> {
var statement = connection.createStatement("INSERT INTO posts (title, content) VALUES (, )")
.returnGeneratedValues("id");
for (var p : data) {
statement.bind(0, p.getTitle()).bind(1, p.getContent()).add();
}
return Flux.from(statement.execute()).flatMap(result -> result.map((row, rowMetadata) -> row.get("id", UUID.class)));
});
对该方法的测试。
@Test
public void testSaveAll() {
var data = Post.builder().title("test").content("content").build();
var data1 = Post.builder().title("test1").content("content1").build();
var result = posts.saveAll(List.of(data, data1)).log("[Generated result]")
.doOnNext(id->log.info("generated id: {}", id));
assertThat(result).isNotNull();
result.as(StepVerifier::create)
.expectNextCount(2)
.verifyComplete();
}
生成的 ID 按预期打印在控制台中。
...
2020-10-08 11:29:19,662 INFO [reactor-tcp-nio-2] reactor.util.Loggers$Slf4JLogger:274 onNext(a3105647-a4bc-4986-9ad4-1e6de901449f)
2020-10-08 11:29:19,664 INFO [reactor-tcp-nio-2] com.example.demo.PostRepositoryTest:31 generated id: a3105647-a4bc-4986-9ad4-1e6de901449f
//.....
2020-10-08 11:29:19,671 INFO [reactor-tcp-nio-2] reactor.util.Loggers$Slf4JLogger:274 onNext(a611d766-f983-4c8e-9dc9-fc78775911e5)
2020-10-08 11:29:19,671 INFO [reactor-tcp-nio-2] com.example.demo.PostRepositoryTest:31 generated id: a611d766-f983-4c8e-9dc9-fc78775911e5
//......
Process finished with exit code 0