表结构同步
本章描述如何根据 KPojo 元数据同步数据库表结构。
syncTable() 会读取 KPojo 的表、列、索引和注释元数据,并按当前数据库方言执行需要的 DDL。
同步 KPojo 表
配置数据源后,调用 syncTable(User()) 或 syncTable<User>()。
kotlin
import com.kotlinorm.Kronos
import com.kotlinorm.annotations.ColumnType
import com.kotlinorm.annotations.PrimaryKey
import com.kotlinorm.annotations.Table
import com.kotlinorm.annotations.TableIndex
import com.kotlinorm.enums.KColumnType
import com.kotlinorm.interfaces.KPojo
@Table("tb_user")
@TableIndex("idx_user_email", ["email"])
data class User(
@PrimaryKey(identity = true)
var id: Int? = null,
@ColumnType(KColumnType.VARCHAR, length = 120)
var email: String? = null,
@ColumnType(KColumnType.VARCHAR, length = 40)
var status: String? = null
) : KPojo
val existed = Kronos.dataSource.table.syncTable(User())表不存在时,Kronos 会创建表并返回 false。
result
existed == false表已存在时,Kronos 会比较列和索引,执行差异 DDL,并返回 true。
result
existed == true添加缺失字段
如果数据库表已有 id 和 email,在 KPojo 中加入 status 后,可以生成 ALTER TABLE 语句。
Mysql
ALTER TABLE `tb_user`
ADD COLUMN `status` VARCHAR(40) NULLPostgreSQL
ALTER TABLE "tb_user"
ADD COLUMN "status" VARCHAR(40) NULL同步索引
@TableIndex 元数据会参与表结构同步。
kotlin
@Table("tb_user")
@TableIndex("idx_user_email", ["email"])
data class User(
@PrimaryKey(identity = true)
var id: Int? = null,
var email: String? = null
) : KPojo
Kronos.dataSource.table.syncTable(User())Mysql
CREATE INDEX `idx_user_email` ON `tb_user` (`email`)PostgreSQL 并发索引使用 @TableIndex 的 concurrently 标记。
concurrently
@TableIndex("idx_user_email", ["email"], concurrently = true)
data class User(
@PrimaryKey(identity = true)
var id: Int? = null,
var email: String? = null
) : KPojoPostgreSQL
CREATE INDEX CONCURRENTLY "idx_user_email" ON "tb_user" ("email")保护结构变更
syncTable() 检测到差异时会执行 ALTER 操作。应用代码只允许指定表执行结构变更时,可以启用 DataGuard。
kotlin
DataGuardPlugin.enable {
alter {
allow {
tableName = "tb_user"
}
}
}
Kronos.dataSource.table.syncTable(User())dropTable() 和 truncateTable() 等破坏性表操作见 📚DataGuard。