无法构建条件为 api 的查询,并与另一个 And Or 一起使用

Can not build query with criteria api using and with another And Or together

我想像这样构建简单的查询:

SELECT * FROM configuration WHERE store_type = 'REGULAR' AND (country = 'SG' OR country = 'AU')

我正在尝试使用标准生成器来实现这一点。 我想做的是像这样创建动态查询生成器:

你可以从对象名称中猜到,它是我将用来动态生成查询的对象

    data class SearchCriteria (
            val property: String,
            val values: List<String>,
            val operation: String
    )

所以在我的休息控制器中,从 UI 我将获得这些对象的列表,并基于它们我想生成查询。

我创建了规范 class,我将在其中构建 CriteriaBuilder 和 Predicates,它看起来像这样:

override fun toPredicate(root: Root<Configuration>, query: CriteriaQuery<*>, builder: CriteriaBuilder): Predicate? {
    val predicates: MutableList<Predicate> = mutableListOf()

    for (criteria in list) {
        if (criteria.operation == "EQUALS") {
            predicates.add(builder.equal(root.get<String>(criteria.key), criteria.values[0]))
        }

        if (criteria.operation == "EQUALS_OR") {
how to build below line dynamically ?
            predicates.add(builder.or(builder.like(root.get<String>(criteria.key), criteria.values[0]), builder.or(builder.like(root.get<String>(criteria.key), criteria.values[1]))))
        }
    }

    return builder.and(*predicates.toTypedArray())
}

所以基本上规则是 "simple" 如果条件操作是 EQUALS 我想有简单的 EQUAL 谓词,这很简单,它会自动工作。

实际的复杂性是将它与 EQUALS_OR 操作混合,我需要在其中添加:

AND (someProperty = "value" or some 属性 = "another value")

换句话说,每次当我得到多个值时得到 EQUALS_OR 运算符,我想构建 AND (property = "value" OR property = "something else") 如果我只有一个值,那么它将很简单并且等于

如您所料,我目前的解决方案 "works",但我不得不对生成器进行硬编码,有谁知道我如何使这条线动态化?

predicates.add(builder.or(builder.like(root.get<String>(criteria.key), criteria.values[0]), builder.or(builder.like(root.get<String>(criteria.key), criteria.values[1]))))

我根据这个指南创建了这段代码:https://attacomsian.com/blog/spring-data-jpa-specifications,基本上是一样的

以防万一有人需要这个,我在下面的代码中解决了这个问题。基本上我必须弄清楚如何正确建立标准。

override fun toPredicate(root: Root<Configuration>, query: CriteriaQuery<*>, builder: CriteriaBuilder): Predicate? {
    val predicates: MutableList<Predicate> = mutableListOf()

    for (criteria in list) {
        if (criteria.operation == "EQUALS") {
            predicates.add(builder.equal(root.get<String>(criteria.key), criteria.values[0]))
        }

        if (criteria.operation == "EQUALS_OR") {
            val equalsOrPredicates: MutableList<Predicate> = mutableListOf()
            for (value in criteria.values) {
                equalsOrPredicates.add(builder.and(builder.like(root.get<String>(criteria.key), value)))
            }

            predicates.add(builder.or(*equalsOrPredicates.toTypedArray()))
        }
    }

    return builder.and(*predicates.toTypedArray())
}