我的資料庫有游戲配置資料和動態用戶資料。每次更新應用程式時,我都會更改很多配置資料(更新記錄并添加新記錄),并且很容易洗掉資料庫并從資產重新創建。除了需要持久化且不受游戲配置更新影響的用戶資料外,所有資料都會更新。
所以我想做什么來避免冗長的遷移代碼:
- 從 Db 讀取用戶資料(2 列)將它們臨時存盤在某處
- 洗掉整個資料庫并從我更新的資產中重新創建
- 將用戶資料寫回這兩列。
從技術的角度來看,我總是覺得很難實作這一點,我想知道是否有人知道它是否可能或以前做過?
uj5u.com熱心網友回復:
如果只有兩列,我建議您將其從 db 中洗掉并將其存盤在其他地方。例如在 SharedPreferences 中。或者這不是你能做的?
我缺少您的實施細節。
如果您使用的是 Room,這將是嘗試Destructive migrations的絕佳機會。構建資料庫時,只需啟用破壞性遷移,當資料庫版本更新時,作業會自動完成。
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
.createFromAsset("database/myapp.db")
.fallbackToDestructiveMigration()
.build()
uj5u.com熱心網友回復:
并且很容易洗掉資料庫并從資產重新創建。
而不是洗掉資料庫重命名它,因此它仍然可用。
使用prePackedDatabase
回呼應用重命名版本中的資料(呼叫回呼時,已復制預打包的資料庫),然后洗掉重命名的資料庫。
您可能會發現這很有用How do I use Room's prepackagedDatabaseCallback?
這是一個未經測驗(但已成功編譯)的示例。
該示例使用以下 @Entity 注釋類TheTable
@Entity
data class TheTable(
@PrimaryKey
val id: Long? = null,
val config1: String,
val user1: String,
val user2: String
)
@Database 注釋類TheDatabase檢查重命名的資料庫是否存在,如果存在,則從重命名的資料庫中提取資料并根據 id 列更新相應的行(假設通常為整數 id 列)。:-
const val DBNAME = "TheDatabase.db"
const val RENAMEDDBNAME = "renamed_$DBNAME"
@Database(entities = [TheTable::class], version = 1, exportSchema = false)
abstract class TheDatabase: RoomDatabase() {
abstract fun getAllDao(): AllDAO
companion object {
var instance: TheDatabase? = null
fun getInstance(context: Context): TheDatabase {
if (instance == null) {
instance = Room.databaseBuilder(context,TheDatabase::class.java, DBNAME)
.allowMainThreadQueries()
.createFromAsset(DBNAME, ppdbc)
.build()
}
return instance as TheDatabase
}
val ppdbc = object : PrepackagedDatabaseCallback() {
@SuppressLint("Range")
override fun onOpenPrepackagedDatabase(db: SupportSQLiteDatabase) {
super.onOpenPrepackagedDatabase(db)
val db_directory = File(db.path).parentFile.path
val renamed_db_path = db_directory File.separator RENAMEDDBNAME
val renamed_db_exists = File(renamed_db_path).exists()
if(renamed_db_exists) {
val renamed_db = SQLiteDatabase.openDatabase(renamed_db_path,null,SQLiteDatabase.OPEN_READWRITE)
db.beginTransaction()
val csr = renamed_db.query("thetable",null,null,null,null,null,"id")
val cv = ContentValues()
while (csr.moveToNext()) {
cv.clear()
cv.put("user1",csr.getString(csr.getColumnIndex("user1")))
cv.put("user2",csr.getString(csr.getColumnIndex("user2")))
db.update("thetable",OnConflictStrategy.IGNORE,cv,"id=?", arrayOf(csr.getLong(csr.getColumnIndex("id"))))
}
db.setTransactionSuccessful() //<<<<< only set if all is ok, if not set then changes would be rolled back
db.endTransaction()
csr.close()
renamed_db.close()
File(renamed_db_path).delete()
}
}
}
}
}
- 顯然,這不是您想要的確切代碼,而純粹是一個可以滿足所提問題的示例,但很可能需要相應地進行調整。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/454991.html
上一篇:如何在雪花中找到隱形字符