首页 > 解决方案 > 使用 Spring Data Specifications,如何将两列的除法与某个输入值进行比较?

问题描述

我在编写 Spring Data Specification 时遇到问题,该规范应该从 DB 搜索查询中过滤掉一些行。

假设数据库中有一张表。该表包含两列,它们都具有 int 类型。我需要一个 Spring 数据规范,它可以按这两列的划分进行过滤。因此,如果这些列是 A 和 B,则需要将 A/B 与某个已知输入值进行比较。

这是我正在尝试做的事情(我正在使用 Kotlin)

return Specification { root: Root<Payment>, _: CriteriaQuery<*>?, builder: CriteriaBuilder ->
        val settlement: Join<Payment, Settlement> = root.join("settlement", JoinType.INNER)

        val decimalExpression = settlement.get<Long>("decimal")
        val multiplierExpression = settlement.get<Long>("multiplier")
        val divisionExpression : Expression<Number> = builder.quot(decimalExpression, multiplierExpression)
        builder.and(
                builder.isNotNull(decimalExpression),
                builder.isNotNull(multiplierExpression),
                builder.greaterThanOrEqualTo(
                        divisionExpression,
                        someKnownLongValue
                ))
    }

settlement的桌子也是。它的某种加入这一事实现在并不重要。

decimalmultiplier是我的 A 和 B 列(我也不需要它们中的任何一个为空,否则我无法划分)。这看起来应该可以工作,但是我遇到了一个问题,因为要比较的类型必须实现Comparable并且CriteriaBuilder#quot()方法返回类型是Expression<Number>. 类Number没有可比性。看起来需要一些班级演员表?但我不确定如何去做,什么是正确的做法。

标签: javaspringkotlinspring-datarelational-database

解决方案


找到了一个很好的解决方法,而不是除法,您可以将等式的两个部分相乘,这样您就不必处理“数字”类

val multipliedExpression = builder.prod(settlement.get<Long>("multiplier"), someKnownLongValue)
builder.greaterThanOrEqualTo(
    settlement.get<Long>("decimal"),
    multipliedExpression
)

推荐阅读