【问题标题】:Room fallbackToDestructiveMigrationRoom fallbackToDestructiveMigration
【发布时间】:2020-04-15 16:32:20
【问题描述】:

我熟悉了 Room,并尝试通过读取 ASSETS 文件夹中的数据库来组装一个小项目。面临这样一个问题:当一个版本的数据库被抛出时,它会抛出一个异常并要求添加MIGRATION。升级版本时,我只需从资产中重写数据库就足够了。为此目的,码头中有一个 fallbackToDestructiveMigration () 方法。但是当我在构建器中指定它时,实际上每次应用程序启动时我的数据库都会被覆盖。我需要的是仅在提高应用程序版本时才从资产中重写数据库。而且我不明白如何实现这种行为。非常感谢您的帮助。

这就是我做所有事情的方式:

这是最简单的例子。

道:

 @Dao
NameDao
@Insert(entity = Name.class, onConflict = OnConflictStrategy.REPLACE)
void insertMe(Name name);

数据库

    @Database(version = 2, entities = [Name::class])
abstract class AppDatabase : RoomDatabase() {
    abstract fun nameDao(): NameDao
}

POJO 实体

@Entity(tableName = "tips_of_the_day")
data class Name(
    @ColumnInfo(name = "name")
    var name: String?
) {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "_id")
    var id: Int = 0
}

应用类

class App : Application() {
private lateinit var appDatabase: AppDatabase


override fun onCreate() {
    super.onCreate()
    appDatabase = getAppDatabase()
}

 fun getAppDatabase(): AppDatabase {

    return Room.databaseBuilder(
        this,
        AppDatabase::class.java, DATABASE_NAME
    )
        .createFromAsset("database/tips_of_the_day.db")
        .fallbackToDestructiveMigration()
        .allowMainThreadQueries()
        .build().also { appDatabase = it }

}

companion object {
    private const val DATABASE_NAME = "tips_of_the_day.db"
}
}

和我的活动

val db: AppDatabase = (application as App).getAppDatabase()
    val dataBase = db.nameDao()


    textView.setOnClickListener(){
        val name: Name = Name( "Anton")
        dataBase.insertMe(name)
        val tableSize: Int = dataBase.all.size
        toast("db size  : $tableSize")
        Log.d("TAG" , "db size  : $tableSize")
    }

原来代码一直有效,直到应用程序重新启动然后数据库被默认覆盖并变成新的(

我不想要这种行为。我需要保存数据库,直到版本更新。如何做到这一点?

【问题讨论】:

  • 澄清一下 - 当您将数据库类中的版本号更改为下一个数字(例如“2”)时,您是否也将附加的数据库从资产文件夹更改为更新的版本 2?
  • @sergiytikhonov 即使我不更改版本号,也不接触数据库,我的应用程序在每次启动时都会覆盖数据。
  • 我不想要这种行为。我需要保存数据库,直到版本更新。如何做到这一点?
  • @Романыч 你是如何解决这个问题的?

标签: android kotlin android-room


【解决方案1】:

我知道这似乎是解决您的问题的一种肮脏方式,但您可以手动管理 migrate-or-not 问题:

fun getAppDatabase(context: Context): AppDatabase {
        // is migration really needed?
        val db = SQLiteDatabase.openDatabase(context.getDatabasePath(DATABASE_NAME).path, null, SQLiteDatabase.OPEN_READONLY)
        val needToMigrate = db.version < dbVersion // your actual version, could be constant
        db.close()
        return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
            .allowMainThreadQueries().apply {
            if (needToMigrate) this.createFromAsset(DATABASE_DIR)
                .fallbackToDestructiveMigration()
        }.build()
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 2021-09-27
    相关资源
    最近更新 更多