无法构建条件为 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())
}
我想像这样构建简单的查询:
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())
}