使用 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
- Driver年龄大于20
- Driver 人在线
- 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();
问题
- 使用
@Embedded
和@Embeddable
存储GPS坐标有什么好处
- 如何使用坐标
找到最近的 driver
我正在使用 Spring Boot 2、Spring Data JPA 2 和 MySQL
这是一项功能,并非所有数据库都能很好地处理(默认情况下)。如果您有一个 MySQL 服务器,那么它能够开箱即用地存储空间坐标,但是例如 PostgreSQL 需要扩展。
您标记了 spring-data-jpa,所以我假设您使用 Hibernate 作为 JPA 提供程序。 Hibernate 也需要扩展才能很好地处理空间坐标。
我有 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
- Driver年龄大于20
- Driver 人在线
- 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();
问题
- 使用
@Embedded
和@Embeddable
存储GPS坐标有什么好处 - 如何使用坐标 找到最近的 driver
我正在使用 Spring Boot 2、Spring Data JPA 2 和 MySQL
这是一项功能,并非所有数据库都能很好地处理(默认情况下)。如果您有一个 MySQL 服务器,那么它能够开箱即用地存储空间坐标,但是例如 PostgreSQL 需要扩展。
您标记了 spring-data-jpa,所以我假设您使用 Hibernate 作为 JPA 提供程序。 Hibernate 也需要扩展才能很好地处理空间坐标。