我正在项目中使用 spring data gemfire ,我正在使用存储库来从缓存中获取查询结果,如下所示:https://docs。spring.io/spring-gemfire/docs/1.3.3.3.release/referene/html/gemfire-repositories.html
下面是我的存储库接口:
@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 = $1")
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查询中找到该键的数据时,我有什么办法返回0或其他值?
或,有什么办法可以获得null
值,以便在没有数据时可以在呼叫者代码中处理它?
在此处指定的OQL中有一个称为NVL
(如果首次表达式评估为null,则允许返回其他值/表达式):https://gemfire.docs.pivotal.io/97/geode/geode/geode/deeverice/query_select/query_select/the_select/the_select_select_select_select_select_select_select_select_statement.html。但是我无法获得如何使用它的正确语法。
请帮忙。谢谢。
首先,在开始之前,一个房屋保留物品...
我看到您在上面的Gemfire文档参考中引用了 Pivotal Gemfire 9.7
,但随后参考Spring data gemfire (SDG)1.3.3.RELEASE
参考文档。我当然希望您不要尝试使用Pivotal Gemfire 9.7
使用SDG 1.3.3.RELEASE
。SDG 1.3.3是基于Pivotal Gemfire 7.0.1的相当日期,不再支持。
我怀疑您不使用SDG 1.3.x
,因此,您可能应该始终在此处,特别是在此处引用最新文档。甚至Google搜索也揭示了最新文档。
另外,您可以参考有关Pivotal Gemfire 版本兼容性矩阵的春季数据,以获取更多详细信息。无论如何...
所以,我写了一个测试课,以更好地了解您的UC。
在我的测试中,我对一个人类班级进行了建模,该课程具有可查询的age
字段/属性。我有一个Person
类型的人格序列,我写了一个与您上面的示例非常相似的查询,以逐年和null-save的方式逐年查询一个人。
事实是,您希望通过返回null
或0
来防止缺乏结果的愿望在储存库的情况下。
对于1,如果您返回了多个结果(例如,如SELECT a.num FROM /SomeRegion a
;即没有谓词),并且未订购结果,那么您将无法知道哪个值为null
,除非您还返回,否则结果集中的键。
当然,情况并非如此,您确实使用谓词通过ID来限定查询(即... WHERE a.id = $1
)。但是,在这种情况下,在查看查询(即SELECT a.num FROM ...
)时尚不清楚,是否没有给定ID的结果(即键),还是简单地 num 是null
。你真的不知道。
我的测试继续说明这一点。
我有2个人["Jon Doe", "Jane Doe"]
,这里。乔恩(Jon)宣布年龄,简(Jane)没有。当然,两个人都存在于缓存中(即"人"地区)。
当我询问乔恩并断言他的年龄时,我得到了预期的结果。
另外,当我查询简并断言她的年龄时,我可以按照这里的预期获得两个值中的1个,即null
或0
(目前0
)(因为我正在使用Null-SAFE查询)。如果我将查询更改为通常的查询,那么Jane的age
的返回值实际上是null
,我可以断言。
但是,当我们开始查询一个不存在的人时,Gemfire的行为很明显。没有结果。我说明了这两种不同的方式(除了使用存储库),直接使用Gemfire的QueryService
API,然后再次使用SDG方便的GemfireTemplate
类,它只是包装了Gemfire查询API(这也是 reposority reposority <的方法>的方法>在引擎盖下;实际上,值存储库是映射/转换功能)。
您可以看到,我必须处理不存在的结果,例如。
在存储库中,因为您使用了自定义查询,因此对于存储库基础结构而言,这并不明显,哪个部分(即查询的中间结果)为 null
。
如果您有SELECT person.address.city.name FROM ...
?
Person null
,地址null
还是CITY null
?应该如何始终如一地处理?该人可能会退出,但地址可能是null
,这可能需要与人或城市为null
的行为不同。
实际上,存储库抽象确实处理 null
返回值,如这里所示。
那么,我们从这里去哪里?
我们有几个选择:
您可以执行并存在检查,首先...
返回personrepository.existsbyId(bobdoe.getName()) ?personRepository.getage(bobdoe.getName()) :0;
您可以在dao中处理存储库的外部(也许可以调整/装饰 repository 并委派用于简单的查询情况,而不是复杂的查询涉及使用
@Query
注释,应谨慎使用)。@repositoryclass 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处理猫王操作员,则类似(在上面更复杂的示例中)...
选择个人?.address?.city?.name来自/人...
无论如何,我希望这给您一些想法。在进行前进之前,我需要在上面的#3上进行更多思考。
如果您还有其他问题/反馈/想法,请在评论中提供它们或随时提交Jira票。
谢谢!