查询结果为空时如何使用 NVL 从 GemFire 获取数据
How to use NVL to get data from GemFire when query result is null
我在一个项目中使用 Spring Data GemFire,并且我使用存储库从缓存中获取查询结果,如下所述:https://docs.spring.io/spring-gemfire/docs/1.3.3.RELEASE/reference/html/gemfire-repositories.html
下面是我的Repository界面:
@Repository
@Region("someRegion")
public interface SomeRegionRepository extends GemfireRepository<CustomObject, Object> {
//Below works when id exists in gemfire region.
//But when id does not exists it
//gives java.lang.IllegalStateException: Unsupported query
@Query("select a.num from /someRegion a where a.id = ")
Integer getNumById(String id);
//Below returns CustomObject instance when id exists in gemfire region.
//But when id does not exists it returns null (Expected)
CustomObject findById(String id);
}
当在 OQL 查询中找不到该键的数据时,有什么方法可以 return 0 或其他值吗?
或者,有没有什么方法可以获得 null
值,以便在没有数据时可以在调用方代码中处理它?
在此处指定的 OQL 中有一个叫做 NVL
的东西(它允许 returning 其他 value/expressions,以防第一个表达式的计算结果为空):https://gemfire.docs.pivotal.io/97/geode/developing/query_select/the_select_statement.html。但是我无法获得如何使用它的正确语法。
请帮忙。谢谢。
首先,在我们开始之前先做一件家政用品...
我看到您在上面的 GemFire 文档参考中引用了 Pivotal GemFire 9.7
,但随后又引用了 Spring Data GemFire (SDG) 1.3.3.RELEASE
参考文档。我当然希望您不要尝试将 SDG 1.3.3.RELEASE
与 Pivotal GemFire 9.7
一起使用。 SDG 1.3.3 非常新,基于 Pivotal GemFire 7.0.1,不再受支持。
我怀疑您没有使用 SDG 1.3.x
,因此您应该始终参考最新的文档,可用 here, and specifically, here. Even a Google Search 显示最新的文档。
此外,您可以参考 Spring Pivotal GemFire Version Compatibility Matrix 的数据了解更多详情。无论如何...
所以,我写了一个test class来更好地了解你的UC。
在我的测试中,我模仿了 Person class with a queryable age
field/property. I have a PersonRepository for the Person
type, and I wrote a very similar query to your example above, to query a person by age, in an usual as well as null-safe 方式。
问题是,在 存储库的情况下,您想要通过 returning null
或 0
来防止结果缺失的愿望是模棱两可的.
对于 1,如果您 return 编辑了多个结果(例如 SELECT a.num FROM /SomeRegion a
;即没有谓词),并且结果没有排序,那么您将无法知道哪个值是哪个键的 null
除非你也在结果集中 returned 键。
当然,这里不是这种情况,您确实使用谓词(即 ... WHERE a.id =
)按 ID 限定了查询。但是,在这种情况下,在查看查询(即 SELECT a.num FROM ...
)时并不清楚给定 ID(即 Key)是否没有结果,或者只是 num 是 null
。你真的不知道。
我的测试继续说明了这一点。
我有2个人["Jon Doe", "Jane Doe"]
,here。乔恩有申报的年龄,而简没有。当然,两个人都存在于缓存中(即"People"区域)。
当我查询 Jon 并断言他的年龄时,我得到 expected result。
或者,当我查询 Jane 并声明她的年龄时,我可以获得两个值中的一个,null
或 0
,如 expected here (currently 0
because I am using the null-safe query). If I change the query to the usual query,然后是 return Jane 的 age
值实际上是 null
,我可以这样断言。
然而,当我们开始查询一个不存在的人时,GemFire 的行为是清楚的;没有结果。我使用 GemFire 的 QueryService
API directly, and then again using SDG's convenient GemfireTemplate
class 说明了这两种不同的方式(除了使用存储库),它简单地包装了 GemFire 查询 API(它也是 Repository[= 使用的方法) 144=] 在幕后;实际上,存储库增加的价值是 mapping/conversion 功能)。
如您所见,我必须处理没有结果的情况,因为 example。
在存储库的情况下,因为您使用了自定义查询,所以对于存储库基础结构来说并不是立即显而易见的,哪一部分(即查询的中间结果)是 null
。
如果你有 SELECT person.address.city.name FROM ...
会怎样?
是人 null
、地址 null
还是城市 null
?这应该如何一致地处理?此人可能会退出,但地址可能是 null
,这可能会导致与人或城市是 null
.
时不同的行为
事实上,Repository 抽象确实处理 null
return 值,如 here.
所示
那么,我们从这里走向何方?
我们有几种选择:
您可以执行 existence check,首先...
return personRepository.existsById(bobDoe.getName())
? personRepository.getAge(bobDoe.getName())
: 0;
你可以在 DAO 中的 Repository 之外处理这个(也许 adapting/decorating Repository并委托简单的查询案例,而不是涉及使用 @Query
注释的复杂查询,应该谨慎使用。
@存储库
class PersonDao {
@Autowired
private PersonRepository personRepository;
Person findById(String name) {
return this.personRepository.findById(name).orElse(null);
}
Integer getAge(String name) {
// Either use the approach in #1, or do https://github.com/jxblum/contacts-application/blob/master/tests-example/src/test/java/example/tests/spring/data/gemfire/NullValueReturningRepositoryQueryMethodIntegrationTests.java#L143-L151.
}
...
}
还是
另一种选择是我们在 SD 中提供额外的支持,类似于...
@Nullable Integer getAge(String name);
或者也许...
Optional<Integer> getAge(String name);
这种方法仍然不能解决歧义问题,需要更多思考。
如果 OQL 处理 Elvis 运算符,那就太好了(在我上面更复杂的示例中)...
SELECT person?.address?.city?.name FROM /People ...
无论如何,我希望这能给你一些想法。在继续前进之前,我需要更多地考虑上面的第 3 点。
如果您还有其他 questions/feedback/ideas,请在评论中提供它们或随时提交 JIRA ticket。
谢谢!
我在一个项目中使用 Spring Data GemFire,并且我使用存储库从缓存中获取查询结果,如下所述:https://docs.spring.io/spring-gemfire/docs/1.3.3.RELEASE/reference/html/gemfire-repositories.html
下面是我的Repository界面:
@Repository
@Region("someRegion")
public interface SomeRegionRepository extends GemfireRepository<CustomObject, Object> {
//Below works when id exists in gemfire region.
//But when id does not exists it
//gives java.lang.IllegalStateException: Unsupported query
@Query("select a.num from /someRegion a where a.id = ")
Integer getNumById(String id);
//Below returns CustomObject instance when id exists in gemfire region.
//But when id does not exists it returns null (Expected)
CustomObject findById(String id);
}
当在 OQL 查询中找不到该键的数据时,有什么方法可以 return 0 或其他值吗?
或者,有没有什么方法可以获得 null
值,以便在没有数据时可以在调用方代码中处理它?
在此处指定的 OQL 中有一个叫做 NVL
的东西(它允许 returning 其他 value/expressions,以防第一个表达式的计算结果为空):https://gemfire.docs.pivotal.io/97/geode/developing/query_select/the_select_statement.html。但是我无法获得如何使用它的正确语法。
请帮忙。谢谢。
首先,在我们开始之前先做一件家政用品...
我看到您在上面的 GemFire 文档参考中引用了 Pivotal GemFire 9.7
,但随后又引用了 Spring Data GemFire (SDG) 1.3.3.RELEASE
参考文档。我当然希望您不要尝试将 SDG 1.3.3.RELEASE
与 Pivotal GemFire 9.7
一起使用。 SDG 1.3.3 非常新,基于 Pivotal GemFire 7.0.1,不再受支持。
我怀疑您没有使用 SDG 1.3.x
,因此您应该始终参考最新的文档,可用 here, and specifically, here. Even a Google Search 显示最新的文档。
此外,您可以参考 Spring Pivotal GemFire Version Compatibility Matrix 的数据了解更多详情。无论如何...
所以,我写了一个test class来更好地了解你的UC。
在我的测试中,我模仿了 Person class with a queryable age
field/property. I have a PersonRepository for the Person
type, and I wrote a very similar query to your example above, to query a person by age, in an usual as well as null-safe 方式。
问题是,在 存储库的情况下,您想要通过 returning null
或 0
来防止结果缺失的愿望是模棱两可的.
对于 1,如果您 return 编辑了多个结果(例如 SELECT a.num FROM /SomeRegion a
;即没有谓词),并且结果没有排序,那么您将无法知道哪个值是哪个键的 null
除非你也在结果集中 returned 键。
当然,这里不是这种情况,您确实使用谓词(即 ... WHERE a.id =
)按 ID 限定了查询。但是,在这种情况下,在查看查询(即 SELECT a.num FROM ...
)时并不清楚给定 ID(即 Key)是否没有结果,或者只是 num 是 null
。你真的不知道。
我的测试继续说明了这一点。
我有2个人["Jon Doe", "Jane Doe"]
,here。乔恩有申报的年龄,而简没有。当然,两个人都存在于缓存中(即"People"区域)。
当我查询 Jon 并断言他的年龄时,我得到 expected result。
或者,当我查询 Jane 并声明她的年龄时,我可以获得两个值中的一个,null
或 0
,如 expected here (currently 0
because I am using the null-safe query). If I change the query to the usual query,然后是 return Jane 的 age
值实际上是 null
,我可以这样断言。
然而,当我们开始查询一个不存在的人时,GemFire 的行为是清楚的;没有结果。我使用 GemFire 的 QueryService
API directly, and then again using SDG's convenient GemfireTemplate
class 说明了这两种不同的方式(除了使用存储库),它简单地包装了 GemFire 查询 API(它也是 Repository[= 使用的方法) 144=] 在幕后;实际上,存储库增加的价值是 mapping/conversion 功能)。
如您所见,我必须处理没有结果的情况,因为 example。
在存储库的情况下,因为您使用了自定义查询,所以对于存储库基础结构来说并不是立即显而易见的,哪一部分(即查询的中间结果)是 null
。
如果你有 SELECT person.address.city.name FROM ...
会怎样?
是人 null
、地址 null
还是城市 null
?这应该如何一致地处理?此人可能会退出,但地址可能是 null
,这可能会导致与人或城市是 null
.
事实上,Repository 抽象确实处理 null
return 值,如 here.
那么,我们从这里走向何方?
我们有几种选择:
您可以执行 existence check,首先...
return personRepository.existsById(bobDoe.getName()) ? personRepository.getAge(bobDoe.getName()) : 0;
你可以在 DAO 中的 Repository 之外处理这个(也许 adapting/decorating Repository并委托简单的查询案例,而不是涉及使用
@Query
注释的复杂查询,应该谨慎使用。@存储库 class PersonDao {
@Autowired private PersonRepository personRepository; Person findById(String name) { return this.personRepository.findById(name).orElse(null); } Integer getAge(String name) { // Either use the approach in #1, or do https://github.com/jxblum/contacts-application/blob/master/tests-example/src/test/java/example/tests/spring/data/gemfire/NullValueReturningRepositoryQueryMethodIntegrationTests.java#L143-L151. } ...
}
还是
另一种选择是我们在 SD 中提供额外的支持,类似于...
@Nullable Integer getAge(String name);
或者也许...
Optional<Integer> getAge(String name);
这种方法仍然不能解决歧义问题,需要更多思考。
如果 OQL 处理 Elvis 运算符,那就太好了(在我上面更复杂的示例中)...
SELECT person?.address?.city?.name FROM /People ...
无论如何,我希望这能给你一些想法。在继续前进之前,我需要更多地考虑上面的第 3 点。
如果您还有其他 questions/feedback/ideas,请在评论中提供它们或随时提交 JIRA ticket。
谢谢!