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 老项目迁移系列,持续更新中。

相关推荐
杉氧2 小时前
深入理解 Compose 重组机制:快照系统如何驱动 UI 精准刷新?
android·架构·android jetpack
召钱熏2 小时前
状态枚举正确≠渲染正确:一个语音按钮的状态机边界修复实录
android·前端
像我这样帅的人丶你还2 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
杉氧2 小时前
深度解析:Jetpack Compose 核心架构与底层原理 —— 十年安卓老兵的“破茧重生”
android·架构·android jetpack
通玄3 小时前
Jetpack Compose 入门系列(七):ViewModel 与界面状态管理
android
落魄Android在线炒饭3 小时前
Android Framework 开发技巧:android.jar 生成与系统快速编译验证
android
如此风景4 小时前
Kotlin Flow操作符学习
android·kotlin
plainGeekDev4 小时前
GreenDAO → Room
android·java·kotlin
weiggle5 小时前
第八篇:ViewModel + Compose——生产级状态管理实践
android
亦暖筑序9 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端