当使用Room时,只要将新表添加到数据库中,就必须在迁移中创建它。不幸的是,Room并没有这样的方法通过只给出类名来创建表。下面的内容是必须具备的
room.createTable(User::class)
奥姆利特
TableUtils.createTable(connectionSource, User::class.java)
数据库
查询目前,您可以在
migrate
你写你的创作
数据库
剧本
db.execSQL("CREATE TABLE IF NOT EXIST `User` (uid INTEGER NON NULL, PRYMARY KEY (`uid`))")
上述方法并没有问题,但会变得复杂和冗长
数据库
创建脚本
-
在构建应用程序之后,
AppDatabase_Impl
-
你包括
exportSchema = true
@Database
注释,它将创建
versionNumber.json
schemas文件夹中文件室数据库的架构。您可以从那里获得创建脚本。
崩溃
数据库
查询,不是
公共关系
无法轻松调试的查询。
所以,我想用面向对象的方法在迁移时创建表。显然,我能想到的唯一方法是使用模型数据类并根据模型的每个字段生成查询。应该是这样的
fun createTable(db: SupportSQLiteDatabase, clazz: KClass<*>) {
val fields = extractColumns(clazz)
val primaryKeys = fields
.filter { it.primaryKey }
.map { it.name }
val createQuery = "CREATE TABLE IF NOT EXISTS `${clazz.simpleName}` (" +
fields.joinToString(", ") { "`${it.name}` ${it.type} ${it.nonNull}" } +
", PRIMARY KEY (" + primaryKeys.joinToString(",") { "`$it`" } +
"))"
db.execSQL(createQuery)
}
fun extractColumns(clazz: KClass<*>): Array<Column>{
val columns = ArrayList<Column>()
for (field in clazz.declaredMemberProperties){
val name = field.findAnnotation<ColumnInfo>()?.name ?: field.name
val type = getSqlType(field.returnType)
val nonNull = if (field.returnType.isMarkedNullable) "" else "NON NULL"
val primaryKey = field.findAnnotation<PrimaryKey>() != null
columns.add(Column(name, type, nonNull, primaryKey))
}
return columns.toTypedArray()
}
但问题是
都有注释
@Retention(RetentionPolicy.CLASS)
只能在编译时访问。它们在运行时不可用。所以我所有的
findAnnotation
null
. 我想在编译时创建,但想不出如何创建。
除了我提到的解决方法外,还有没有其他创建表的方法不涉及前两种复制粘贴方法?
顺便说一句,我没有考虑
fallbackToDestructiveMigration