Kotlin Exposed:如何用DAO及onUpdate级联自动创建子表记录
解答
不能通过onUpdate级联函数实现这个需求——onUpdate级联是用于父表记录更新时同步处理子表的逻辑,完全不涉及父表插入新记录的场景。不过可以通过Kotlin Exposed的DAO机制实现自动创建子表记录的需求,下面提供两种实用方案:
方案一:利用DAO的afterInsert钩子
在父表的DAO类中重写afterInsert方法,插入父记录后自动触发子记录的创建逻辑。
示例代码:
// 定义表结构 object ParentTable : IntIdTable() { val name = varchar("name", 50) } object ChildTable : IntIdTable() { val colA = reference("col_a", ParentTable).uniqueIndex() // 关联父表ID,唯一约束保证一一对应 val colB = varchar("col_b", 50).default("默认值") // 设置默认值 } // DAO实体类 class ParentEntity(id: EntityID<Int>) : IntEntity(id) { companion object : IntEntityClass<ParentEntity>(ParentTable) var name by ParentTable.name val child by ChildEntity referencedOn ChildTable.colA override fun afterInsert() { super.afterInsert() // 父记录插入完成后,自动创建对应子记录 ChildEntity.new { colA = this@ParentEntity // colB会自动使用默认值,无需手动赋值 } } } class ChildEntity(id: EntityID<Int>) : IntEntity(id) { companion object : IntEntityClass<ChildEntity>(ChildTable) var colA by ParentEntity referencedOn ChildTable.colA var colB by ChildTable.colB }
使用方式:
transaction { ParentEntity.new { name = "父记录1" } // 此时ChildTable会自动生成一条对应记录:colA为该父记录ID,colB为预设默认值 }
方案二:事务内手动关联插入
如果不想依赖DAO的钩子方法,也可以在同一个事务中先插入父记录,紧接着创建子记录,保证操作的原子性。
示例代码:
transaction { val parent = ParentEntity.new { name = "父记录2" } // 手动创建对应子记录 ChildEntity.new { colA = parent // colB自动使用默认值 } }
补充说明
- 若要完全通过数据库层面触发逻辑,可以创建数据库触发器,但这不属于Exposed DAO的功能范畴。
- 无论用哪种方案,都要将操作放在同一个
transaction中,确保父、子记录的创建要么同时成功,要么同时回滚,避免数据不一致。
内容的提问来源于stack exchange,提问作者mars8
相关产品推荐
相关产品推荐

