该篇使用较传统方式来修改表的主键,步骤
- 在表结构中将原主键删除
- 添加新主键
- 升级数据库表
升级数据库表步骤
- 创建一个新临时表
- 将旧表中数据复制到临时表
- 删除旧表
- 将临时表重命名
之前数据库表结构如下:
@Entity(tableName = "NewsFeedData")
@TypeConverters(StringTypeConverter::class,DateConverters::class)
@Parcelize
data class NewsBeanResponse(
@PrimaryKey
var item_id : String,
var cover_url : String?,
var last_time: Date,// 最近插入时间
) : Parcelable
当前升级后的结构如下:
@Entity(tableName = "NewsFeedData")
@TypeConverters(StringTypeConverter::class,DateConverters::class)
@Parcelize
data class NewsBeanResponse(
// 新增字段id并设置为主键
@PrimaryKey(autoGenerate = true)
var id : Int,
// @PrimaryKey
var item_id : String,
var cover_url : String?,
var last_time: Date,// 最近插入时间
) : Parcelable
经过将表结构修改过后,我们需要升级数据库版本号:
// version 版本号从1升到2
@Database(entities = [ NewsBeanResponse::class ],version = 2,exportSchema = false)
abstract class DataBase : RoomDatabase() {
abstract fun getNewsBeanResponseDao() : NewsBeanResponseDao
}
开始迁移
object BrowserDBHelper {
lateinit var database: DataBase
fun init(context: Context, name: String) {
database = Room.databaseBuilder(context, DataBase::class.java, name)
.addMigrations(MIGRATION_1_2)
.build()
}
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
// 创建一个新表
database.execSQL("CREATE TABLE `NewsFeedDataTemp` ( `id` INTEGER PRIMARY KEY NOT NULL, `cover_url` TEXT ,`item_id` TEXT NOT NULL, `last_time` INTEGER NOT NULL DEFAULT 0,)")
// 将旧表中数据复制到新表中
database.execSQL("INSERT INTO NewsFeedDataTemp (cover_url,item_id,last_time) select cover_url , item_id , last_time from NewsFeedData")
// 删除旧表
database.execSQL("DROP TABLE NewsFeedData")
// 将新表生命名为旧表名
database.execSQL("ALTER TABLE NewsFeedDataTemp RENAME TO NewsFeedData")
}
}
至此,修改表主键任务完成。
网友评论