查询结果为空时如何使用 NVL 从 GemFire 获取数据

我在一个项目中使用Spring Data GemFire,并且我正在使用存储库从缓存中获取查询结果,如此处所述:https ://docs.spring.io/spring-gemfire/docs/1.3.3.RELEASE/reference/ 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/developing/query_select/the_select_statement.html 。但我无法获得如何使用它的正确语法。


阿波罗的战车
浏览 84回答 1
1回答

肥皂起泡泡

首先,在我们开始之前有一个家务...我看到您在上面的 GemFire 文档参考中引用了Pivotal GemFire ,但随后参考了 Spring&nbsp;Data GemFire&nbsp;(SDG)参考文档。我当然希望您不要尝试将 SDG与 Pivotal GemFire一起使用。SDG 1.3.3 已经过时,基于 Pivotal GemFire 7.0.1,不再受支持。9.71.3.3.RELEASE1.3.3.RELEASE9.7我怀疑您没有使用 SDG&nbsp;1.3.x,因此您可能应该始终参考最新的文档,可在此处获得,特别是在此处。即使是Google 搜索也会显示最新的文档。此外,您可以参考Spring Data for Pivotal GemFire&nbsp;版本兼容性矩阵了解更多详细信息。反正...所以,我写了一个测试类来更好地理解你的 UC。在我的测试中,我用一个可查询的field/property建模了一个Person 类。我有一个PersonRepository类型,我写了一个与你上面的例子非常相似的查询,按年龄查询一个人,以通常以及空安全的方式。agePerson问题是,您希望通过返回来防止结果缺失的愿望,null或者在Repositories0的情况下是模棱两可的。对于 1,如果您返回了多个结果(例如,如SELECT a.num FROM /SomeRegion a; 即没有谓词),并且结果没有排序,那么您将无法知道哪个值是null哪个键,除非您还返回结果中的键放。当然,这里不是这种情况,您确实使用谓词(即... WHERE a.id = $1)通过 ID 限定了查询。但是,在这种情况下,在查看查询(即SELECT a.num FROM ...)时,并不清楚给定 ID(即 Key)是否没有结果,或者只是num是null。你真的不知道。我的测试继续说明这一点。我有2个人["Jon Doe", "Jane Doe"],在这里。乔恩有一个公布的年龄,而简没有。当然,这两个人都存在于缓存中(即“人”区域)。当我查询 Jon 并断言他的年龄时,我得到了预期的结果。或者,当我查询 Jane 并断言她的年龄时,我可以得到两个值中的 1 个,或者null或0,正如这里所预期的那样(目前0因为我正在使用null-safe query)。如果我将查询更改为通常的查询,那么 Jane's 的返回值age实际上是null,我可以这样断言。然而,当我们开始查询一个不存在的人时,GemFire 的行为是明确的;没有结果。我说明了这两种不同的方式(除了使用存储库),直接使用 GemFire 的QueryServiceAPI,然后再次使用 SDG 的便捷GemfireTemplate类,它简单地包装了 GemFire 查询 API(这也是存储库在后台使用的方法;真的,存储库添加的值是映射/转换功能)。如您所见,我必须处理没有结果的情况,例如.在存储库的情况下,由于您使用了自定义查询,因此存储库基础架构并不能立即看出哪一部分(即查询的中间结果)是null.如果你有SELECT person.address.city.name FROM ...呢?是人null、地址null还是城市null?这应该如何始终如一地处理?人可能会离开,但地址可能会离开null,这可能会导致与人或城市都存在不同的行为null。事实上,Repository抽象确实处理了null返回值,正如可以在此处看到的那样。那么,我们该何去何从?我们有几种选择:你可以执行和存在检查,首先......返回 personRepository.existsById(bobDoe.getName()) ?personRepository.getAge(bobDoe.getName()) : 0;您可以在 DAO 中的存储库之外处理此问题(也许调整/装饰存储库并委托简单的查询案例,而不是涉及使用@Query注释的复杂查询,应该谨慎使用)。@Repository 类 PersonDao {@Autowiredprivate&nbsp;PersonRepository&nbsp;personRepository;Person&nbsp;findById(String&nbsp;name)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;this.personRepository.findById(name).orElse(null);}Integer&nbsp;getAge(String&nbsp;name)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Either&nbsp;use&nbsp;the&nbsp;approach&nbsp;in&nbsp;#1,&nbsp;or&nbsp;do&nbsp;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。如果您有其他问题/反馈/想法,请在评论中提供或随时提交JIRA 票证。谢谢!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java