带有复杂可为空对象的JPA @Query

时间:2018-10-17 14:26:55

标签: java jpa kotlin spring-data-jpa spring-data

我正在建立一个getAll查询的存储库,该查询使用复杂的类型参数进行过滤,例如:

@Query("""
    SELECT c FROM City c
    WHERE :filter IS NULL OR c.code LIKE %:#{#filter.code}%
    """)
fun getAllCitiesFiltered(@Param("filter") filter: MyFilter?) : List<City>

MyFilter类是一个简单的POJO:

class MyFilter {
    var code: String? = null
    var description: String? = null
}

在我的代码中的某个时刻,我叫getAllCitiesFiltered(filter),而这个filter可以为null或可以将其属性之一设置为null。我有两个问题:

  • 如何处理filter可为空的事实?现在的方式(如上),每当传递一个null值时,我都会得到一个异常EL1007E: Property or field 'code' cannot be found on null
  • HQL中是否有一种不太丑陋的方法来处理以下事实:属性codedescription可能为null,而当它们为null时,我不想按它们过滤吗?我现在想到的唯一方法就是做类似... WHERE filter.code IS NULL or filter.code LIKE %c.code%
  • 的事情

我是JPA的新手,所以不确定使用@Query是否是这里的最佳方法。我也乐意提出修改建议。

谢谢!

Alan Hay建议后进行编辑

我正在使用QueryDSL,来自C#/ LINQ背景,发现它很棒。 “问题”是我正在做这样的事情:

val city = QCity.city
var query = JPAQuery<City>(entityManager).from(city)

if (filter?.code != null)
    query = query.where(city.code.eq("BH"))

if (filter?.description != null)
    query = query.where(city.description.eq("Belo Horizonte"))

除了切换和if / else'ing之外,还有其他更好的写方法吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

最好的方法是使用接口默认方法:

interface CityJpaRepository : JpaRepository<City, Int> {
  fun findByCodeLike(code: String) : List<City>

  fun findByFilter(filter: MyFilter?) : List<City> {
    return filter?.code?.let { findByCodeLike(it.code) } ?: findAll()
  }
}