我想建立这样的简单查询:
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
)
因此,在我的rest控制器中,我将从UI获得这些对象的列表,并基于它们我想生成查询。
我创建了规范类,将在其中构建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())
}
因此,如果条件运算为等式,则规则基本上是“简单的”,我想拥有简单的等式谓词,这很简单,它将自动运行。
实际复杂度是将其与EQUALS_OR操作混合,在这里我需要添加此内容:
AND(someProperty =“ value”或some property =“另一个值”)
换句话说,每次当我获得多个值时都得到EQUALS_OR运算符时,如果我只有一个值,我想构建AND (property = "value" OR property = "something else")
,那将很简单并且等于
您可以假设,我当前的解决方案“有效”,但是我必须使用硬代码构建器,有人知道我如何使这条线动态化吗?
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())
}