SQLite 手动升级 → Room Migration

SQLite 手动升级 → Room Migration

老写法(Java + SQLiteOpenHelper)

java 复制代码
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (oldVersion < 2) {
        db.execSQL("ALTER TABLE item ADD COLUMN description TEXT");
        db.execSQL("ALTER TABLE item ADD COLUMN category TEXT DEFAULT '其他'");
    }
    if (oldVersion < 3) {
        db.execSQL("ALTER TABLE item ADD COLUMN create_time INTEGER DEFAULT 0");
        // 迁移旧数据
        db.execSQL("UPDATE item SET create_time = ? WHERE create_time = 0",
                new Object[]{System.currentTimeMillis()});
    }
}

问题在哪里

版本号和 SQL 全靠自己维护,多版本连续升级逻辑如果写错了顺序会丢数据。升级前无法做校验,升级后无法做验证,也没有编译期安全。最容易线上灾难的代码之一------ALTER TABLE 在 Android 上对 SQLite 的兼容性差异很大。

新写法(Room Migration)

kotlin 复制代码
val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(db: SupportSQLiteDatabase) {
        db.execSQL("ALTER TABLE item ADD COLUMN description TEXT")
        db.execSQL("ALTER TABLE item ADD COLUMN category TEXT NOT NULL DEFAULT '其他'")
    }
}

val MIGRATION_2_3 = object : Migration(2, 3) {
    override fun migrate(db: SupportSQLiteDatabase) {
        db.execSQL("ALTER TABLE item ADD COLUMN create_time INTEGER NOT NULL DEFAULT 0")
        db.execSQL("UPDATE item SET create_time = ? WHERE create_time = 0",
                arrayOf(System.currentTimeMillis()))
    }
}

// 构建
val db = Room.databaseBuilder(context, AppDatabase::class.java, "app.db")
        .addMigrations(MIGRATION_1_2, MIGRATION_2_3)
        .build()

未匹配的版本跳转用 fallbackToDestructiveMigration()

kotlin 复制代码
Room.databaseBuilder(context, AppDatabase::class.java, "app.db")
        .fallbackToDestructiveMigration()
        .build()

一句话注意

Migration(startVersion, endVersion) 的版本号必须严格连续 ,不能跳号。Room 会按顺序应用所有匹配的 Migration。比如数据库当前版本是 1,目标版本是 3,Room 会自动依次执行 MIGRATION_1_2MIGRATION_2_3

fallbackToDestructiveMigration() 会删库重建------升级后旧数据全部丢失。只有开发阶段可以用,线上千万不能配。如果线上有用户跳版本更新(比如 1 直接升到 4),确保 1→2、2→3、3→4 的 Migration 全部写好了,Room 会自动串联。


Java Android 老项目迁移系列,持续更新中。

相关推荐
好好沉淀3 分钟前
@ExcelIgnoreUnannotated 和 @AutoMapper 详解
java
愚公移码23 分钟前
蓝凌EKP18产品:流程虚拟机(PVM)
java·开发语言·前端
驰骋工作流32 分钟前
流程引擎BPM设计之:流程消息
java·工作流引擎·bpm·jflow·ccflow
时间的拾荒人36 分钟前
MySQL 视图详解
android·数据库·mysql
dogstarhuang38 分钟前
从 0 到 1 搭建可收费的 API 开放平台(实战)
java·架构·api
祉猷并茂,雯华若锦1 小时前
Appium 3.x安卓按键与通知栏操作全指南
android·appium
VortMall1 小时前
『平台去经营化』平台治理能力全新重构|VortMall微服务商城系统v1.3.10
java·大数据·微服务·商城系统·开源商城·vortmall·去经营化
吴声子夜歌1 小时前
Redis 3.x——集群故障转移
java·数据库·redis·集群
Java面试题总结2 小时前
mybatis插件
java·tomcat·mybatis
码农coding2 小时前
android 12 SurfaceFlinger开机启动分析
android