Sqlite 方法在文件室中创建表
当使用Room时,只要将新表添加到数据库中,就必须在迁移中创建它。不幸的是,Room并没有这样的方法通过只给出类名来创建表。下面的内容是必须具备的Sqlite 方法在文件室中创建表,sqlite,kotlin,database-migration,android-room,annotation-processing,Sqlite,Kotlin,Database Migration,Android Room,Annotation Processing,当使用Room时,只要将新表添加到数据库中,就必须在迁移中创建它。不幸的是,Room并没有这样的方法通过只给出类名来创建表。下面的内容是必须具备的 room.createTable(User::class) 类似的方法存在于OrmLite中 其必要性来自于仅使用简单的SQLite查询创建表的复杂性。目前,您可以在migrate中编写创建SQLite脚本 上面的方法并没有问题,但若您有50个字段,那个么它会变得复杂和长的SQLite脚本。显然,您不是自己编写的,有两种方法可以让Room为您自动生
room.createTable(User::class)
类似的方法存在于OrmLite中
其必要性来自于仅使用简单的SQLite查询创建表的复杂性。目前,您可以在migrate
中编写创建SQLite脚本
上面的方法并没有问题,但若您有50个字段,那个么它会变得复杂和长的SQLite脚本。显然,您不是自己编写的,有两种方法可以让Room为您自动生成Create脚本,这样您就可以复制过去
AppDatabase\u Impl
,并创建所有必要的表。您可以从那里获得查询@Database
注释中包含exportSchema=true
,它将在schemas文件夹中创建房间数据库的versionNumber.json
模式。您可以从那里获得创建脚本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()
}
funcreateTable(db:SupportSQLiteDatabase,clazz:KClass){
val字段=提取列(clazz)
val primaryKeys=字段
.filter{it.primaryKey}
.map{it.name}
val createQuery=“创建表如果不存在`${clazz.simpleName}`(”+
fields.joinToString(“,”{`${it.name}`${it.type}${it.nonNull}}+
,主键(“+primaryKeys.joinToString(“,”{“`it`”}+
"))"
db.execSQL(createQuery)
}
列(clazz:KClass):数组{
val columns=ArrayList()
for(类别申报成员属性中的字段){
val name=field.findAnnotation()?.name?:field.name
val type=getSqlType(field.returnType)
val nonNull=if(field.returnType.isMarkedNullable)“,else“nonNull”
val primaryKey=field.findAnnotation()!=null
columns.add(列(名称、类型、非null、primaryKey))
}
返回columns.toTypedArray()
}
但问题是房间注释都是用
@Retention(RetentionPolicy.CLASS)
只能在编译时访问。它们在运行时不可用。因此,我所有的findAnnotation
方法都将返回null
。我想在编译时创建,但想不出如何创建
所以,我的问题是,有没有办法在编译时生成CREATE脚本?如果有,怎么做
除了我提到的解决方法外,还有没有其他创建表的方法不涉及前两种复制粘贴方法
顺便说一句,我没有考虑退回到破坏性迁移。我的意思是,谁会希望他们的用户丢失所有数据?从当前更新的
Room
开始,实际上有一种方法可以使用注释处理创建SQL查询。使用注释处理,您必须编写小型库,在构建时为您生成Room
查询
创建注释处理库
并不简单,这里是相关问题
您能提供代码示例吗?我使用房间+科特林。这是代码示例@Database(entities=[ProductOffer::class],version=1)@TypeConverters(Converters::class)抽象类AppDatabase:RoomDatabase(){abstract fun productOfferDao():productOfferDao}。Room通过迁移自动生成实现。您所说的代码示例是什么意思?如果您指的是我如何创建AppDatabase
,那么它与我提出的问题有什么关系?我可以提供,但您也可以在中找到,Room通过迁移自动生成实现是什么意思
您为我提供了有用的信息,可以使用exportSchema选项创建表查询。谢谢:)顺便说一句,我同意你的看法,这种方法不专业。我已经提供了更多关于表格创建的信息
db.execSQL("CREATE TABLE IF NOT EXIST `User` (uid INTEGER NON NULL, PRYMARY KEY (`uid`))")
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()
}