前言
Room持久性庫在SQLite的基礎(chǔ)上提供了一個抽象層,讓用戶能夠在充分利用SQLite的強大功能的同時,獲享更強健的數(shù)據(jù)庫訪問機制。
場景
在實際開發(fā)中,開發(fā)者肯定會遇到數(shù)據(jù)庫版本的升級,Room自然也是提供類似api供開發(fā)者升級數(shù)據(jù)庫版本使用的。
正文
數(shù)據(jù)庫實體對象:
首先是創(chuàng)建數(shù)據(jù)庫實體對象,具體字段自定義,這里不闡述,這里的表名稱就叫"Download"
@Entity(tableName = "Download")
open class DownloadBean(
@PrimaryKey
@NonNull
var aaa: String = "",//0
XXXXX
)
數(shù)據(jù)庫對象:
其次是創(chuàng)建數(shù)據(jù)庫對象,entities就是剛才的數(shù)據(jù)庫實體對象,version就是數(shù)據(jù)庫的版本,DownloadDao是數(shù)據(jù)庫操作的接口
@Database(
entities = [DownloadBean::class],
version = 1
)
abstract class DownloadDatabase : RoomDatabase() {
abstract fun downloadDao(): DownloadDao
}
數(shù)據(jù)庫接口:
這里定義了數(shù)據(jù)庫的增刪改查操作,相信大家都看得懂
@Dao
interface DownloadDao {
@Insert
fun insert(data: DownloadBean)
@Delete
fun delete(data: DownloadBean)
@Update
fun update(data: DownloadBean)
@Query("SELECT * FROM download WHERE aaa=:value")
fun find(value: String): DownloadBean?
@Query("SELECT * FROM download")
fun findAll(): MutableList<DownloadBean>?
}
數(shù)據(jù)庫管理類:
最后是數(shù)據(jù)庫管理類,這里獲取數(shù)據(jù)庫對象的單例,然后操作Dao去改變數(shù)據(jù)庫,這里的"Download"是數(shù)據(jù)庫名稱,和剛才的表名稱不要混淆了
class DownloadDbManager {
companion object {
private var db: DownloadDatabase? = null
fun getInstance(): DownloadDatabase {
if (db == null) {
db = Room.databaseBuilder(
MarketApplication.getRootContext(),
DownloadDatabase::class.java,
"Download"
)
.allowMainThreadQueries()//允許在主線程中查詢
.build()
}
return db!!
}
}
//操作DownloadDao
}
數(shù)據(jù)庫升級:
重點來了,如何升級數(shù)據(jù)庫,假設(shè)一開始只有aaa這個字段,現(xiàn)在是版本1,后面我們要升級數(shù)據(jù)庫到版本2,增加bbb和ccc字段,該怎么做呢?
很簡單,首先創(chuàng)建Migration,然后使用addMigrations()去添加Migration即可,這里的MIGRATION_1_2就是從數(shù)據(jù)庫版本1升級到版本2時的操作,我這里新增了bbb和ccc兩個String類型的字段。
class DownloadDbManager {
companion object {
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Download " + " ADD COLUMN bbb TEXT ")
database.execSQL("ALTER TABLE Download " + " ADD COLUMN ccc TEXT ")
}
}
private var db: DownloadDatabase? = null
fun getInstance(): DownloadDatabase {
if (db == null) {
db = Room.databaseBuilder(
MarketApplication.getRootContext(),
DownloadDatabase::class.java,
"Download"
)
.allowMainThreadQueries()//允許在主線程中查詢
.addMigrations(MIGRATION_1_2)
.build()
}
return db!!
}
}
//Database操作Dao
}
同時切記別忘記升級數(shù)據(jù)庫版本到2。
@Database(
entities = [DownloadBean::class],
version = 2
)
abstract class DownloadDatabase : RoomDatabase() {
abstract fun downloadDao(): DownloadDao
}
數(shù)據(jù)庫跳躍升級:
假設(shè)我們下一個版本又要新增ddd和eee字段呢?但用戶還停留在版本1,如何升級到版本3呢?
實際開發(fā)中肯定不可能永遠都是1->2,2->3的,實際上1->3、1->4或者2->4這種場景居多,這個時候我們可以幫用戶去跳躍升級,幫用戶從1->3,1->4,所以如何跳躍升級呢?
其實是一樣的,因為addMigrations()可以添加多個Migration,只要把規(guī)則寫清楚即可。
class DownloadDbManager {
companion object {
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Download " + " ADD COLUMN bbb TEXT ")
database.execSQL("ALTER TABLE Download " + " ADD COLUMN ccc TEXT ")
}
}
private val MIGRATION_2_3 = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Download " + " ADD COLUMN ddd TEXT ")
database.execSQL("ALTER TABLE Download " + " ADD COLUMN eee INTEGER ")
}
}
private var db: DownloadDatabase? = null
fun getInstance(): DownloadDatabase {
if (db == null) {
db = Room.databaseBuilder(
MarketApplication.getRootContext(),
DownloadDatabase::class.java,
"Download"
)
.allowMainThreadQueries()//允許在主線程中查詢
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build()
}
return db!!
}
}
//Database操作Dao
}
還是別忘記升級數(shù)據(jù)庫版本到3。
@Database(
entities = [DownloadBean::class],
version = 3
)
abstract class DownloadDatabase : RoomDatabase() {
abstract fun downloadDao(): DownloadDao
}