Я хочу построить простой запрос, подобный этому:
SELECT * FROM configuration WHERE store_type = 'REGULAR' AND (country = 'SG' OR country = 'AU')
И я пытаюсь добиться этого с помощью построителя критериев. Я пытаюсь создать динамический c построитель запросов, например, так:
Вы можете догадаться по имени объекта, это объект, который я буду использовать для динамического создания запроса
data class SearchCriteria (
val property: String,
val values: List<String>,
val operation: String
)
Итак, в моем контроллере rest из пользовательского интерфейса я получу список этих объектов, и на основе них я хочу сгенерировать запрос.
Я создал класс спецификации, в котором я буду строить 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, я хочу иметь простой предикат EQUAL, это просто и будет работать автоматически.
Фактическое осложнение состоит в том, чтобы смешать его с операцией EQUALS_OR, где мне нужно добавить это:
AND (someProperty = "value" или some property = "another value")
Другими словами, каждый раз, когда я получаю оператор EQUALS_OR, когда получаю несколько значений, я хочу построить AND (property = "value" OR property = "something else")
, если у меня есть только одно значение, тогда оно будет простым и равным
Как вы можете предположить, мой текущее решение "работает", но мне пришлось с трудом создавать код, кто-нибудь знает, как я могу сделать эту строку динамической c?
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, в основном это одно и то же