首页 > 解决方案 > 如何使用 JPA(休眠)捕获数据库中动态生成的列的值?

问题描述

假设我有以下 JPA 实体:

@Entity
@Table(name = "places")
public class Place {

    @Id @GeneratedValue
    private Long id;
    private String name;
    private double lat;
    private double lng;

    // Getters and setters
}

还有一个名为 PlacesRepository 的 Spring 存储库,它具有本机查询:

public interface PlacesRepository extends CrudRepository<Place, Long> {

    @Query(
        value = "SELECT *, DISTANCE(lat,lng,:myLat,:myLng) AS distance " +
                "FROM places ORDER BY distance",
        nativeQuery = true
    )
    List<Place> nearestPlaces(
        @Param("myLat") double myLat,
        @Param("myLng") double myLng
    );

}

该 DISTANCE 功能只是为了举例说明本机数据库功能。因为我使用的是 PostGIS,所以它相当于 ST_Distance。它使用每条记录的坐标和方法的坐标返回距离。

如何捕获该“距离”字段而无需将其存储在表中???我不想存储它,因为它是动态的。我只想将实体作为 json 返回。

标签: javaspringhibernatejpaspring-data-jpa

解决方案


这里的一个选项是使用 HQL,而不是本机查询。例如,您可以创建一个简单的结果类:

class PlaceToDistancePair {
    private Place place;
    private double distance;
    public PlaceToDistancePair(Place place, double distance) {
        this.place = place;
        this.distance = distance;
    }
// getters and setters
}

然后你的@Query 会看起来像这样:

@Query(
        value = "SELECT new PlaceToDistancePair(p, DISTANCE(lat,lng,:myLat,:myLng)) FROM places p")
List<PlaceToDistancePair> placeToDistanceList;

您可以在此处找到更多信息,也可以select new 在此处找到select new map建筑,这可能也适合您将 Place 映射到距离而无需PlaceToDistancePair分类。

但是,如果您的函数(例如 ST_Distance)没有在休眠方言中注册,您需要自己注册。在“使用 Hibernate Dialect 注册 SQL 函数”部分中查看Vlad 如何执行此操作。

您还可以选择使用 CriteriaBuilder API,它更加灵活,但需要更多代码。在这里阅读更多


推荐阅读