首页 > 解决方案 > 带变量的注释参数

问题描述

在我们的 Spring 项目中,我想将 Java 存储库转换为 Kotlin。Repository 是一个带有方法和注释的接口,其中包含数据库查询作为参数。有几种方法,但查询中最复杂和最长的部分是重复的。在 Java 中,我们将字符串作为变量插入到查询中。

Kotlin 中的当前解决方案无法编译,因为“注释参数必须是编译时常量”。

处理这个问题的最佳方法是什么?

interface PlaceRepository : JpaRepository<Place, UUID>, JpaSpecificationExecutor<Place> {

    val HAVERSINE_FORMULA: String
        get() =
            """
                (6371 * acos(cos(radians(CAST(CAST(:latitude AS string) AS double)))
                * cos(radians(p.gpsLatitude)) * cos(radians(p.gpsLongitude) - radians(CAST(CAST(:longitude AS string) AS double)))
                + sin(radians(CAST(CAST(:latitude AS string) AS double))) * sin(radians(p.gpsLatitude))))
            """

    @Query("""
        SELECT p AS place,
             $HAVERSINE_FORMULA AS distance
        FROM Place p
        WHERE p.code = :code
    """)
    fun findByCode(
        code: String,
        latitude: Double,
        longitude: Double
    ): Optional<PlaceWithDistanceDTO>
}

谢谢

标签: kotlinjpaannotations

解决方案


您可以尝试使用伴生对象,如下所示:

interface PlaceRepository : JpaRepository<Place, UUID>, JpaSpecificationExecutor<Place> {

    companion object {
        private const val HAVERSINE_FORMULA =
            """
                (6371 * acos(cos(radians(CAST(CAST(:latitude AS string) AS double)))
                * cos(radians(p.gpsLatitude)) * cos(radians(p.gpsLongitude) - radians(CAST(CAST(:longitude AS string) AS double)))
                + sin(radians(CAST(CAST(:latitude AS string) AS double))) * sin(radians(p.gpsLatitude))))
            """
    }

    @Query("""
        SELECT p AS place,
             $HAVERSINE_FORMULA AS distance
        FROM Place p
        WHERE p.code = :code
    """)
    fun findByCode(
        code: String,
        latitude: Double,
        longitude: Double
    ): Optional<PlaceWithDistanceDTO>
}

推荐阅读