如何在公开 kotlin 的情况下实现 orderBy 中枚举的自定义订单?

问题描述 投票:0回答:1

我有以下枚举作为字符串存储在数据库中:

enum class Status {

    PENDING, ACCEPTED, REJECTED
}

还有下面的Table类:

object Examples : Table("examples") {

    val id = integer("id")
    val status = enumerationByName("status", 100, Status::class)

    override val primaryKey = PrimaryKey(id)
}

当我在公开的查询中使用以下 orderBy 时,它按字母顺序排序(首先接受)。

Examples.selectAll().orderBy(Table.status to SortOrder.ASC)

但我需要不同的订单;应该先是 PENDING,然后是 ACCEPTED,最后是 REJECTED。

我该如何实施?我使用的是mysql数据库。

我尝试了以下方法,但它无法编译,我不知道出了什么问题。

                .orderBy(
                    Case(Examples.status)
                        .When(Status.PENDING).Then(1)
                        .When(Status.ACCEPTED).Then(2)
                        .When(Status.REJECTED).Then(3)
                        .Else(3)
                )
mysql kotlin enums sql-order-by kotlin-exposed
1个回答
0
投票

这里介绍了如何在 JetBrains/Exposes 中进行一般排序

val EmployeeTable = object : IntIdTable() {
    val employeeId = integer("employee_id")
    val name = text("name")
    val city = text("city")
    val salary = integer("salary")
}.also { SchemaUtils.drop(it);SchemaUtils.create(it) }

data class Employee(val employeeId: Int, val name: String, val city: String, val salary: Int)

val employees = listOf(
    Employee(1, "Shalaga44", "Ajman", 44),
    Employee(2, "Shalaga44", "Ajman", 44),
    Employee(3, "No One", "Ajman", 44),
    Employee(4, "No One", "No where", 44),
    Employee(5, "No One", "No where", 0),
)
EmployeeTable.batchInsert(employees.shuffled()) {
    this[EmployeeTable.employeeId] = it.employeeId
    this[EmployeeTable.name] = it.name
    this[EmployeeTable.city] = it.city
    this[EmployeeTable.salary] = it.salary
}

val conditions = listOf(
    Op.build { EmployeeTable.employeeId inList employees.take(2).map { it.employeeId } },
    Op.build { EmployeeTable.name ilike "%${employees.first().name}%" },
    Op.build { EmployeeTable.city eq employees.first().city },
    Op.build { EmployeeTable.salary greaterEq employees.first().salary }
)

class Plus<T : Number>(
    val expr0: Expression<T>,
    val expr1: Expression<T>
) : Expression<T>() {
    override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit =
        queryBuilder { append("(", expr0, "+", expr1, ")") }
}


val matchScoreExpression = conditions
    .mapIndexed { index, condition ->
        val caseWhen = CaseWhen<Int>(null)
        caseWhen.When(
            cond = condition,
            result = intLiteral(1)
        )
        val caseWhenElse = caseWhen.Else(intLiteral(0))
        caseWhenElse

    }.reduce { acc, expression ->
        Plus(acc, expression)
    }


val query = EmployeeTable
    .slice(EmployeeTable.fields + matchScoreExpression)
    .select { conditions.reduce { acc, op -> acc or op } }
    .orderBy(matchScoreExpression, SortOrder.DESC)


val result = query.map {
    Employee(
        employeeId = it[EmployeeTable.employeeId],
        name = it[EmployeeTable.name],
        city = it[EmployeeTable.city],
        salary = it[EmployeeTable.salary],
    )
}

assertThat(result)
    .isEqualTo(employees.sortedBy { it.employeeId }.dropLast(1))

SchemaUtils.drop(EmployeeTable)


© www.soinside.com 2019 - 2024. All rights reserved.