java - 如何使用 Mono 处理可为空的字段还是 R2dbc 在 Spring 中提供的 DatabaseClient?
问题描述
我不知道如何使用 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)
某处的事情。如果这显然是不可能的,我仍然有兴趣找出一种方法来尽可能有效地实现这一点,因为我正在使用它。感谢任何反馈。
解决方案
这是两个问题:
- 如何以流畅的风格将可能为空的值绑定到
Statement
/ ?DatabaseClient
- 如何让数据库解决剩下的问题?
R2DBC 和 Spring Data R2DBCnull
通过要求将值绑定到您的值Statement
或绑定null
. 没有接受可能为空的参数的方法。有两个原因:
- 您应该处理可空性以明确那里发生的情况。
null
这是处理可空值而不是隐式处理的好习惯。的隐含性质null
是导致最多错误的原因。 - 数据库要求明确。带有占位符的参数化语句包含在两个块的执行端:SQL 语句本身和参数绑定(描述符)。参数描述符需要与占位符、类型信息 (
VARCHAR
,BIT
,INT
, ...) 和实际值的关联。通过使用值调用bind(…)
,驱动程序可以派生类型信息。绑定null
值时,驱动程序需要其他类型的信息。否则,我们无法执行查询。
话虽如此:
- 没有类似的 API
bindPotentiallyNull("auditId", entity.getTx().getId(), Integer.class)
- 您不能在 SQL 查询中执行任何操作,因为绑定参数信息是由辅助方法提供的。
在谈论存储过程时,我们面临着类似的问题,因为存储过程需要有关 in/out/in-out 参数的更多详细信息。我们讨论了潜在的包装器类型,例如
Parameters.in(@Nullable T value, Class<? super T> valueType)
所以这些可以用作包装器
bind("auditId", Parameters.in(entity.getTx().getId(), Integer.class))
更多细节:
推荐阅读
- c# - C#发送数据最快的方式sql还是(TCPListener)
- c++ - 将长位数组映射到查找表
- elasticsearch - 带有通配符的 Elasticsearch 索引字段并搜索它
- unity3d - 如何在 ARCore 中使用 AssetBundled 3D 资产,而不是在 Andy Prefab 上使用
- android - 在 Android Unity 上找不到 gdiplus.dll
- php - 如何在循环内回显一个单词两次和另一个单词一次
- json - Jenkinsfile JSON 对象返回 null
- c++ - 英特尔 DAAL 2017 Beta 更新 1 编译错误
- amazon-web-services - 如何使用第三方应用程序登录亚马逊 mws
- node.js - 如何使用 Nodejs 在 IBM watson 助手中添加对话节点的更新多个响应