【问题标题】:calculating distance between two coordinates SQL + Criteria Builder计算两个坐标之间的距离 SQL + Criteria Builder
【发布时间】:2021-04-23 20:01:09
【问题描述】:

所以在我的代码中,我希望能够使用一些参考坐标来检查范围内的坐标。 一开始我使用的是一些原生 SQL 查询,例如:

  @Query(
          value = "SELECT * FROM event " +
                  "   inner join event_location location on location.id = event.location_id\n" +
                  "  where Round( ST_Distance_Sphere(\n" +
                  "    Point(?1 , ?2 )," +
                  "    Point(location.longtitude , location.latitude ), 4326), 2) <= ?3",
          nativeQuery = true)
  List<Event> findAllEventsInRange(double longtitude, double latitude, String range);

它工作得很好,但现在我想将规范与标准生成器一起使用。 老实说,我不知道如何在 where 关键字之后写条件。

谁能告诉我该怎么做?

编辑: 实体已定义。我已经创建了现在加入两个表的规范 - 事件和事件位置:

public static Specification<Event> filter(Search search){
return (root, cq, cb) -> {
      Predicate location = null;

      List<Predicate> result = new ArrayList<>();

      if(search.getLat() != null && search.getLng() != null && search.getRange() != null) {
         Join<Event,EventLocation> join = root.join("eventLocation", JoinType.LEFT);
            }

            return cb.and(result.toArray(new Predicate[result.size()]));
        };
    }

现在我需要创建一个正确的谓词,它将与 WHERE 之后的语句执行相同的操作。我知道标准构建器上有一个函数可以用于一些本机 sql 函数,但不知道如何在我的情况下使用它并与其他不同的 sql 函数结合使用。

【问题讨论】:

  • 我认为您没有为表格定义实体。那将是第一步。在那之后,我个人会尝试摆脱“nativeQuery = true”。在这种情况下,现代开发工具可以帮助您确保 JQL-Query 在语法上是正确的。在我看来,“Criteria Builder”并不直观。你可能在类型安全方面获得了什么,但你却失去了清晰度。

标签: java sql hibernate jpa


【解决方案1】:

您需要为此使用通用函数调用语法,如下所示:

public static Specification<Event> filter(Search search){
    return (root, cq, cb) -> {
      Predicate location = null;

      List<Predicate> result = new ArrayList<>();

      if(search.getLat() != null && search.getLng() != null && search.getRange() != null) {
         Join<Event,EventLocation> join = root.join("eventLocation", JoinType.LEFT);
         result.add(
           cb.le(
             cb.function("Round", String.class,
               cb.function("ST_Distance_Sphere", String.class, 
                 cb.function("Point", String.class, 
                   cb.literal(search.getLat()),
                   cb.literal(search.getLng())
                 ),
                 cb.function("Point", String.class, 
                   join.get("longtitude"),
                   join.get("latitude ")
                 ),
                 cb.literal(4326)
               ),
               cb.literal(2)
             ),
             cb.literal(search.getRange())
           )
         );
      }
  
      return cb.and(result.toArray(new Predicate[result.size()]));
   };
}

【讨论】:

    猜你喜欢
    • 2020-02-12
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 2016-07-16
    • 1970-01-01
    相关资源
    最近更新 更多