Kotlin 如何使用exposed根据传入参数添加多个或过滤条件?
我必须使用参数值向查询添加Kotlin 如何使用exposed根据传入参数添加多个或过滤条件?,kotlin,kotlin-exposed,Kotlin,Kotlin Exposed,我必须使用参数值向查询添加或条件 示例:select*来自电子邮件=”的用户abc@xyz.com“或电话=“1234123412” 用户可以发送两个字段,也可以只发送一个字段。我希望在每个字段的循环中执行此操作,并将每个字段添加到或where条件中 val query = Users.selectAll() **var predicates = Op.build { Users.id inList listOf<Int>()}** for((k, v) in params) {
或
条件
示例:select*来自电子邮件=”的用户abc@xyz.com“或电话=“1234123412”代码>
用户可以发送两个字段,也可以只发送一个字段。我希望在每个字段的循环中执行此操作,并将每个字段添加到或where
条件中
val query = Users.selectAll()
**var predicates = Op.build { Users.id inList listOf<Int>()}**
for((k, v) in params) {
val value = URLDecoder.decode(v.first(), "UTF-8")
predicates = when(k) {
"email" -> predicates.or(Users.email eq value)
"phone" -> predicates.or(Users.phone eq value)
}
}
query.andWhere { predicates }
是否看到false=true
?这是因为,要使用或方法,我必须使用一个条件进行初始化。下面给出的代码段是为初始化谓词而添加的一行不必要的代码
var predicates = Op.build { Users.id inList listOf<Int>()}
var-predicates=Op.build{Users.id inList listOf()}
初始化它的正确方法是什么,这样我就可以无缝地将多个或和和谓词添加到查询中?一个技巧是将谓词初始化为null
,并定义自己的或和和在操作?
上:
//此处不确定x的类型是否正确,wiki没有给出确切的签名
//可能还需要@JvmName来允许重载
fun Op?.or(x:Op)=如果(this!=null)this.or(x)else x
...
变量谓词:Op?=无效的
...
谓词=when(k){
“email”->谓词。或(Users.email eq值)
“phone”->谓词。或(Users.phone eq值)
}
我怀疑这是否值得复杂化:正如Giacomo的评论所提到的,数据库肯定会优化您的原始代码。首先,我建议优化您的代码,如:
val params = mapOf<String, List<String>>()
val emails = params.filterKeys { it == "email" }.map { URLDecoder.decode(it.value.first(), "UTF-8") }
val phones = params.filterKeys { it == "phone" }.map { URLDecoder.decode(it.value.first(), "UTF-8") }
if (emails.isEmpty() && phones.isEmpty()) {
error("No suitable params were provided")
} else {
Users.select {
Users.email inList emails or (Users.phone inList phones)
}
}
然后像这样使用它:
val query = Users.selectAll()
for((k, v) in params) {
val value = URLDecoder.decode(v.first(), "UTF-8")
predicates = when(k) {
"email" -> query.orWhere { Users.email eq value }
"phone" -> query.orWhere{ Users.phone eq value }
}
}
AFAIK几乎所有最终创建SQL的框架/库都使用这种子句。从DSL的角度来看,它们只是更好。如果存在0或1个条件,它们将删除对或
和和
的特殊处理。SQL引擎将简单地忽略它们,因此没有真正的缺点。看看hibernate生成的查询。它们充满了1=0
和1=1
之类的东西。所以很可能你不能轻易地移除它们。
val params = mapOf<String, List<String>>()
val emails = params.filterKeys { it == "email" }.map { URLDecoder.decode(it.value.first(), "UTF-8") }
val phones = params.filterKeys { it == "phone" }.map { URLDecoder.decode(it.value.first(), "UTF-8") }
if (emails.isEmpty() && phones.isEmpty()) {
error("No suitable params were provided")
} else {
Users.select {
Users.email inList emails or (Users.phone inList phones)
}
}
fun Query.orWhere(andPart: SqlExpressionBuilder.() -> Op<Boolean>) = adjustWhere {
val expr = Op.build { andPart() }
if(this == null) expr
else this or expr
}
val query = Users.selectAll()
for((k, v) in params) {
val value = URLDecoder.decode(v.first(), "UTF-8")
predicates = when(k) {
"email" -> query.orWhere { Users.email eq value }
"phone" -> query.orWhere{ Users.phone eq value }
}
}