当查询结果为null时,如何使用NVL从Gemfire获取数据



我正在项目中使用 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的方式逐年查询一个人。

事实是,您希望通过返回null0来防止缺乏结果的愿望在储存库的情况下

对于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个,即null0(目前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返回值,如这里所示。

那么,我们从这里去哪里?

我们有几个选择:

  1. 您可以执行并存在检查,首先...

    返回personrepository.existsbyId(bobdoe.getName()) ?personRepository.getage(bobdoe.getName()) :0;

  2. 您可以在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.
    }
    ...
    

    }

    仍然

  3. 另一个选择是让我们在SD中提供额外的支持,这是...

    的线条

    @Nullable Integer getAge(String name);

    或也许...

    Optional<Integer> getAge(String name);

    仍然这种方法无法解决歧义问题,并且需要更多的思考。

  4. 真正好的是,如果OQL处理猫王操作员,则类似(在上面更复杂的示例中)...

    选择个人?.address?.city?.name来自/人...

无论如何,我希望这给您一些想法。在进行前进之前,我需要在上面的#3上进行更多思考。

如果您还有其他问题/反馈/想法,请在评论中提供它们或随时提交Jira票。

谢谢!

相关内容

  • 没有找到相关文章

最新更新