You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Kotlin Exposed DSL查询映射与事务注解的技术咨询

你的两个问题解答+代码修正

嘿,我来帮你搞定这两个问题,顺便把你代码里的映射问题给修正了~

1. 如何将Select查询的结果映射到实体类?

你代码里的映射方式是不对的——map { User }只是引用了User类本身,并没有把查询返回的ResultRow转换成实体实例;map { User.it }的写法也不符合语法,根本没法正确提取行数据。

假设你用的是Exposed框架(从代码风格来看大概率是),正确的做法是遍历查询返回的每一行ResultRow,从中取出对应字段的值来构建你的实体对象。举个完整的例子:

首先定义你的实体类和数据库表:

// 这是你的业务实体类
data class User(val id: Int, val username: String)

// 这是Exposed的数据库表定义
object Users : Table() {
    val id = integer("id").autoIncrement()
    val username = varchar("username", 50)
}

然后修正Repository里的映射逻辑:

object UserRepository {
    fun getAll(): List<User> {
        // 遍历每一行ResultRow,提取字段构建User实例
        return Users.selectAll().map { row ->
            User(
                id = row[Users.id],
                username = row[Users.username]
            )
        }
    }

    fun get(id: Int): User? {
        // 查询后取第一个结果(或null),同时正确映射
        return Users.select { Users.id eq id }
            .map { row ->
                User(
                    id = row[Users.id],
                    username = row[Users.username]
                )
            }
            .firstOrNull()
    }
}

简单说:row[Users.id]就是从查询结果行中取出id字段的值,以此类推,把这些值传入实体类的构造函数,就完成了映射。

2. 是否存在@Transactional注解用于执行查询?

当然存在!@Transactional注解不仅用于写操作(插入、更新、删除),也可以用在查询方法上——尤其是当你需要在事务上下文里执行查询(比如和写操作联动、需要特定事务隔离级别),或者想标记查询为只读以让数据库做优化时。

如果用Spring框架:

直接给方法加上@Transactional注解,并且建议加上readOnly = true来优化查询性能:

import org.springframework.transaction.annotation.Transactional

object UserRepository {
    @Transactional(readOnly = true)
    fun getAll(): List<User> {
        return Users.selectAll().map { row ->
            User(row[Users.id], row[Users.username])
        }
    }

    @Transactional(readOnly = true)
    fun get(id: Int): User? {
        return Users.select { Users.id eq id }
            .map { row -> User(row[Users.id], row[Users.username]) }
            .firstOrNull()
    }
}

如果用Exposed自带的事务管理:

可以用transaction { ... }代码块来包裹查询逻辑,这是Exposed原生的事务处理方式:

object UserRepository {
    fun getAll(): List<User> {
        return transaction {
            Users.selectAll().map { row ->
                User(row[Users.id], row[Users.username])
            }
        }
    }

    fun get(id: Int): User? {
        return transaction {
            Users.select { Users.id eq id }
                .map { row -> User(row[Users.id], row[Users.username]) }
                .firstOrNull()
        }
    }
}

如果是Spring+Exposed的混合场景,两种方式都可以选,不过通常保持一致的风格会更好。


内容的提问来源于stack exchange,提问作者Bassirou Rabo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:46:48