如何在JetBrains Exposed中将Dao对象转换为Model?
解决方案:DAO 到可序列化 Model 的手动映射
Exposed 本身没有内置 DAO 到数据传输对象(DTO/Model)的自动转换工具,你需要手动编写映射逻辑,处理实体间的关联关系,同时确保在事务上下文内完成转换(因为 Exposed 的关联是懒加载的)。
1. 定义可序列化的 Model 类
首先创建带序列化注解的数据类(这里以 Kotlinx Serialization 为例,你也可以用其他序列化库如 Jackson):
import kotlinx.serialization.Serializable @Serializable data class AuthorModel( val id: Int, val name: String, val email: String? ) @Serializable data class ChapterModel( val id: Int, val bookId: Int, val title: String, val content: String ) @Serializable data class BookModel( val id: Int, val title: String, val isbn: String, val author: AuthorModel, val chapters: List<ChapterModel> )
2. 给 DAO 类添加扩展转换函数
通过 Kotlin 扩展函数,给每个 DAO 类添加转 Model 的方法,处理一对一和一对多关联:
// AuthorDao 转 AuthorModel fun AuthorDao.toModel() = AuthorModel( id = id.value, name = name, email = email ) // ChapterDao 转 ChapterModel fun ChapterDao.toModel() = ChapterModel( id = id.value, bookId = book.id.value, title = title, content = content ) // BookDao 转 BookModel,核心处理关联关系 fun BookDao.toModel(): BookModel { // 注意:必须在事务内调用此方法,否则懒加载的关联会抛出会话关闭异常 val author = author.toModel() // 一对一关联直接转换 val chapters = chapters.toList().map { it.toModel() } // 一对多关联转列表后逐个转换 return BookModel( id = id.value, title = title, isbn = isbn, author = author, chapters = chapters ) }
3. 在事务中执行转换
所有 DAO 操作和转换必须包裹在 transaction 块内,确保关联数据能正常加载:
// 获取并转换 Book 实例 val bookModel = transaction { BookDao.findById(1)?.toModel() } // 之后即可将 bookModel 序列化为 JSON 返回给客户端
4. 性能优化(可选)
如果数据量较大,直接转换可能触发 N+1 查询(查询 Book 后再逐个查 Author 和 Chapters),可以用 Exposed 的预加载功能优化:
val bookModel = transaction { BookDao.find { Books.id eq 1 } .withReferences(Book::author, Book::chapters) // 预加载关联数据 .firstOrNull() ?.toModel() }
内容的提问来源于stack exchange,提问作者mars8
相关产品推荐
相关产品推荐

