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 }
    }
}