如何将存储50万+数据的SQLite数据库迁移至Room数据库?
将现有SQLite数据库(50万+数据)迁移至Room的实现方案
针对大数量级的SQLite到Room迁移,分两种场景给出实操步骤,同时兼顾性能与数据完整性:
场景1:原SQLite与Room结构完全匹配
如果原表的列名、数据类型、主键约束和Room实体完全一致,可直接让Room接管现有数据库:
定义匹配的Room实体
确保@Entity的tableName与原SQLite表名完全一致,字段名、类型严格对应原表:@Entity(tableName = "user_info") data class User( @PrimaryKey(autoGenerate = true) val id: Long = 0, val username: String, val register_time: Long, val is_active: Int )配置Room数据库类
指定数据库名称与原SQLite文件名一致,版本号对齐原数据库的user_version(无版本号则设为1)。若需要升级版本,添加空Migration避免Room销毁数据:@Database(entities = [User::class], version = 2) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao companion object { fun getInstance(context: Context): AppDatabase { return Room.databaseBuilder( context.applicationContext, AppDatabase::class.java, "old_user_db.db" // 原SQLite文件名 ) .addMigrations(MIGRATION_1_2) .build() } // 空迁移:仅处理版本号变更,不修改表结构 val MIGRATION_1_2 = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) {} } } }验证迁移结果
启动应用后,通过Room DAO执行count()查询,确认数据总数与原数据库一致,随机抽查几条数据验证内容正确性。
场景2:原SQLite与Room结构存在差异
若原表结构需要调整(如列名修改、类型转换、字段增删),需批量读取原数据并转换后插入Room:
批量读取原数据
通过原生SQLiteOpenHelper或Room的SupportSQLiteDatabase访问原表,逐批读取数据:suspend fun migrateOldData(oldDbPath: String, appDb: AppDatabase) { val oldDb = SQLiteDatabase.openDatabase(oldDbPath, null, SQLiteDatabase.OPEN_READONLY) val cursor = oldDb.rawQuery("SELECT id, name, reg_date FROM old_user_table", null) val batchSize = 1000 val userList = mutableListOf<User>() val userDao = appDb.userDao() // Room事务内批量插入,避免频繁IO withTransaction { while (cursor.moveToNext()) { val id = cursor.getLong(cursor.getColumnIndexOrThrow("id")) // 转换原数据格式,比如将字符串日期转为时间戳 val regTime = cursor.getString(cursor.getColumnIndexOrThrow("reg_date")).toTimestamp() val username = cursor.getString(cursor.getColumnIndexOrThrow("name")).trim() userList.add(User(id, username, regTime, 1)) // 每1000条执行一次插入,控制内存占用 if (userList.size >= batchSize) { userDao.insertBatch(userList) userList.clear() } } // 插入剩余数据 if (userList.isNotEmpty()) { userDao.insertBatch(userList) } } cursor.close() oldDb.close() }定义Room批量插入DAO
在DAO中添加批量插入方法,提升插入效率:@Dao interface UserDao { @Insert suspend fun insertBatch(users: List<User>) }
核心注意事项
- 数据库路径:确保原SQLite文件位于Room默认路径(
/data/data/[包名]/databases/),若在其他位置,需先关闭原数据库连接,再复制文件到目标路径,避免文件锁定。 - 事务强制使用:所有数据插入必须在事务中执行,否则50万条数据的插入会触发ANR。
- 内存控制:批量读取时限制每批数据量(如1000条),避免一次性加载全量数据导致OOM。
- 版本管理:严格对齐原数据库版本与Room的版本号,Migration必须覆盖所有版本升级路径,防止Room自动销毁重建数据库。
内容的提问来源于stack exchange,提问作者Lalit chaudhary
相关产品推荐
相关产品推荐

