使用 Spring 数据 JPA 条件查询查找最近的驱动程序

Find Nearest Drivers using Spring Data JPA Criteria Query

我有 driver 详细信息,如下所示。

[
  {
    "name": "Martin",
    "age": 37,
    "status": "online",
    "deleted": false,
    "place": {
      "name": "Mali",
      "lat": 18.341002,
      "lon": -1.700659
    }
  },
  {
    "name": "John",
    "age": 27,
    "status": "offline",
    "deleted": false,
    "place": {
      "name": "Oregon",
      "lat": 18.393135,
      "lon": -1.810474
    }
  }
  :
  :
  :
]

我已经使用 JPA 2.0 将详细信息存储到我的数据库中。在许多博客中,我看到人们使用 @Embedded 并将地点坐标实体定义为 @Embedded@Embeddable 来存储 GPS 坐标(我不知道它会有什么优势),所以我想在我的 Driver 中做同样的事情,如下所示

Driver.java

@Entity
@Table(
    name = "driver",
    uniqueConstraints = @UniqueConstraint(name = "uc_drivers_id", columnNames = {"id"})
)
public class Driver implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Id
    @Column(name="name", nullable = false)
    private String name;

    @Embedded
    private City city;

    @Column(name="age")
    private Integer age;

    @Column(name="status")
    private String status;

    @Column(name="deleted")
    private Boolean deleted;

    :
    :
    :
}

Place.java

@Embeddable
public class Place {

    @Column(name = "location")
    private final Point location;

    @Column(name = "name")
    private String name;

    @JsonProperty
    public double getLatitude()
    {
        return this.location.getY();
    }

    @JsonProperty
    public double getLongitude()
    {
        return this.location.getX();
    }
    :
    :
    :
}

场景

我想找到符合以下条件的所有 driver

  1. Driver年龄大于20
  2. Driver 人在线
  3. Driver距离我的位置坐标最近 30 公里的人(比如说 18.226253,-1.980688)

我已经使用 Criteria 实现了前两个条件,如下所示,但不知道如何实现第三个条件

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Driver> criteriaQuery = criteriaBuilder.createQuery(Driver.class);
Root<Driver> entity= criteriaQuery.from(Driver.class);
Predicate agePredicate = criteriaBuilder.greaterThan(entity.get("age"), 20);
Predicate jobPredicate = criteriaBuilder.equal(entity.get("status"), "online");
Predicate wherePredicate = criteriaBuilder.and(agePredicate, jobPredicate);
TypedQuery<Driver>  query = entityManager.createQuery(criteriaQuery.select(entity).where(wherePredicate));
return query.getResultList();

问题

  1. 使用@Embedded@Embeddable存储GPS坐标有什么好处
  2. 如何使用坐标
  3. 找到最近的 driver

我正在使用 Spring Boot 2、Spring Data JPA 2 和 MySQL

这是一项功能,并非所有数据库都能很好地处理(默认情况下)。如果您有一个 MySQL 服务器,那么它能够开箱即用地存储空间坐标,但是例如 PostgreSQL 需要扩展。

您标记了 spring-data-jpa,所以我假设您使用 Hibernate 作为 JPA 提供程序。 Hibernate 也需要扩展才能很好地处理空间坐标。

看看this article