代码之家  ›  专栏  ›  技术社区  ›  KCK

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

  •  0
  • KCK  · 技术社区  · 6 年前

    我在用 在项目中,我使用存储库从缓存中获取查询结果,如下所述: 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 值以便在没有数据时在调用方代码中处理它?

    NVL (如果第一个表达式的计算结果为空,则允许返回其他值/表达式)在此处指定的OQL中: https://gemfire.docs.pivotal.io/97/geode/developing/query_select/the_select_statement.html . 但我无法得到正确的语法如何使用它。

    0 回复  |  直到 6 年前
        1
  •  1
  •   John Blum    6 年前

    首先,在我们开始之前,先准备一件家居用品。。。

    我看到你提到 关键宝石 9.7 在上面的GemFire文档参考中,然后参考Spring (可持续发展目标) 1.3.3.RELEASE 参考文件。我当然希望你不要用SDG 带枢轴金火 . SDG 1.3.3是相当过时的,基于Pivotal GemFire 7.0.1,不再受支持。

    我怀疑你没有用SDG 1.3.x ,因此您可能应该始终参考最新的可用文档 here ,特别是, here . 甚至是 Google Search 显示最新的文档。

    另外,你可以参考 关键GemFire的弹簧数据 Version Compatibility Matrix 更多细节。不管怎样。。。

    所以,我写了 test class

    在我的测试中,我模拟了 Person class 带着疑问 age field/property PersonRepository 对于 Person 键入,然后我编写了一个与上面的示例非常相似的查询,以按年龄查询一个人,在 usual null-safe 态度。

    问题是,你想通过返回来防止没有结果 null 0 在这种情况下是模棱两可的 存储库

    对于1,如果您返回了多个结果(例如 SELECT a.num FROM /SomeRegion a ;也就是说,如果没有谓词),并且结果没有排序,那么您将无法知道哪个值是 对于哪个键,除非还返回结果集中的键。

    ... WHERE a.id = $1 ). 但是,在这种情况下,在查看查询时并不清楚(即。 SELECT a.num FROM ... ),无论给定的ID(即密钥)是否没有结果,或者 无效的

    我的测试继续说明这一点。

    ["Jon Doe", "Jane Doe"] , here . 乔恩有法定年龄,简没有。当然,两个人都存在于缓存中(即“人”区域)。

    expected result .

    或者,当我查询Jane并断言她的年龄时,我可以得到两个值中的一个 0个 expected here (目前 因为我用的是 null-safe query ). 如果我将查询更改为 usual query ,则返回Jane的 年龄 无效的 ,我可以这样断言。

    但是,当我们开始查询一个不存在的人时,GemFire的行为很明显,没有结果。我用GemFire的 QueryService API GemfireTemplate class ,它简单地包装了GemFire查询API(它也是 存储库 实际上,存储库增加的价值是映射/转换功能)。

    example .

    在存储库的情况下,因为使用了自定义查询,所以对于存储库基础结构来说,它不是很明显,即查询的中间结果是 .

    SELECT person.address.city.name FROM ... ?

    是人 ,地址 无效的 或城市 ? 应该如何一致地处理这个问题?此人可能退出,但地址可能是 ,这可能会导致不同的行为 .

    事实上 抽象处理 无效的 here .

    我们有几个选择:

    1. existence check ,首先。。。

      返回personRepository.existsById(bobDoe.getName()) ? personRepository.getAge(bobDoe.getName()) :0;

    2. 你可以在外面处理这个 在DAO中(可能修改/装饰 存储库 @Query 注释,应谨慎使用)。

      @存储库 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. @Nullable Integer getAge(String name);

      或者。。。

      Optional<Integer> getAge(String name);

      但这种方法并不能解决歧义问题,需要更多的思考。

    4. 如果OQL处理一个Elvis操作符(在我上面更复杂的例子中)会非常好。。。

      选择人员?。地址?。城市?。姓名/联系人。。。

    不管怎样,我希望这能给你一些建议。在前进之前,我需要考虑以上3点。

    如果您有其他问题/反馈/想法,请在评论中提供,或随时提交 JIRA ticket .

    谢谢!

    推荐文章