【发布时间】:2019-08-18 16:38:08
【问题描述】:
我不知道如何使用 spring-webflux (reactive) 在 R2dbc (java) 中构建一个有效的查询。使用 R2dbc 提供的 DatabaseClient 对象(或者,一个 Connection 对象),我似乎只能调用这两种方法之一的不同变体:bind(Object field, Object value) 或bindNull(Object field, Class<?> type)。如果我在 Java 中有一个模式和一个相应的类,并且有多个可为空的字段,那么我应该如何有效地处理这个问题?
举个例子:
public Flux<Item> saveOrUpdate(Item entity) {
Mono<Connection> connection = this.connection;
Flux<? extends Result> itemFlux = connection
.doOnError(e -> e.printStackTrace())
.flatMapMany(connect -> connect.createStatement(INSERT_OR_UPDATE_ITEM)
.bind("itemId", entity.getItemId()).returnGeneratedValues("itemid")
.bind("auditId", entity.getTx().getId())
.bind("itemNum", entity.getItemNum())
.bind("itemCat", entity.getItemCat()) //nullable
// How would I know when to use this?
.bindNull("sourcedQty", Integer.class) //nullable
.bind("makeQty", entity.getMakeQty())
.bind("nameShown", entity.getNameShown()) //nullable
.bind("price", entity.price())
.bind("dateCreated", entity.getDateCreated()) //nullable
.add()
.execute())...
...
}
或
public Mono<Item> saveOrUpdate(Item entity){
Mono<Item> itemMono = databaseClient.execute.sql(INSERT_OR_UPDATE_ITEM)
.bind("itemId", entity.getItemId()).returnGeneratedValues("itemid")
.bind("auditId", entity.getTx().getId())
.bind("itemNum", entity.getItemNum())
.bind("itemCat", entity.getItemCat())
.bind("sourcedQty", entity.getSourcedQty())
.bind("makeQty", entity.getMakeQty())
.bind("nameShown", entity.getNameShown())
.bind("price", entity.price())
.bind("dateCreated", entity.getDateCreated())
.as(Item.class)
.fetch()
.one()...
...
}
对于我的可空字段,我当然可以用 .bindNull 替换 .bind。问题是,如果我调用绑定,则该值不能为空。如果我调用bindNull,则该值必须为null。我将如何根据我的值实际上是否为空来调用其中一个?我已经知道我可以为每个场景创建一堆方法,或者调用一些类似 retryOnError 的方法。但是,如果我想做insertOrUpdate(List<Item> items),这将浪费大量时间/资源。理想情况下,我想以某种方式在某处做类似于if (field == null) ? bindNull("field", field.class) : bind("field", myObj.field) 的事情。如果这显然不在桌面上,我仍然有兴趣找出一种方法来尽可能有效地实现这一点,因为我正在使用它。感谢任何反馈。
【问题讨论】:
-
澄清您的问题:您希望保留流畅的风格,同时可能绑定
null值,而您正在询问如何实现这一目标。 -
听起来是一种可以接受的表达方式。我的 actuql 数据集包含的空值比我在这里制作的样本多。例如,我想让与此类似的方法几乎与使用 jdbc 执行准备好的语句一样有效。我不想使用挂钩或包装器或插入不符合数据库中已有数据约定的值。所以从这个意义上说,我非常关心风格。但我对需要妥协的想法持开放态度。我是 r2dbc 和响应式的新手,所以我很可能忽略了一个简单的解决方案或一个聪明的解决方法。
-
我也很想知道一种编写 sql 语句的方法,这样我就可以使用 .bind 并让数据库解决剩下的问题。
标签: java spring-data spring-webflux spring-data-r2dbc r2dbc