上一篇在介紹 DataStore 時有提到,如果是較複雜的資料存儲建議使用 Room 來執行,今天就來教紹一下 Room 的操作吧!以下如有解釋不清或是描述錯誤的地方還請大家多多指教:
Room 是由 SQLite 提供抽象層,讓我們可以方便取用資料,主要由三個元件組成:
dependencies {
def room_version = "2.4.3"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// To use Kotlin annotation processing tool (kapt)
kapt "androidx.room:room-compiler:$room_version"
}
先設計好要存在 db 的 table,我想將城市現在天氣狀況存起來,所以列了幾個欄位:
@Entity(tableName = "city_table")
class CityEntities (
@PrimaryKey @ColumnInfo(name = "id") val id: Int,
@ColumnInfo(name = "cityName") val cityName: String,
@ColumnInfo(name = "week") val week: String,
@ColumnInfo(name = "cityCurrentTemp") val currentTemp: String,
@ColumnInfo(name = "cityCurrentWind") val currentWind: String,
@ColumnInfo(name = "cityCurrentRain") val currentRain: String,
@ColumnInfo(name = "cityCurrentWet") val currentWet: String
)
目前需要寫入顯示及刪除
@Dao
interface CityDAO {
@Query("SELECT * FROM cityTable")
fun getAll(): List<CityEntities>
@Insert
fun insertAll(vararg users: CityEntities)
@Delete
fun delete(user: CityEntities)
}
建立連線的 databse
@Database(entities = [CityEntities::class], version = 1)
abstract class CityDatabase: RoomDatabase() {
abstract fun cityDao(): CityDAO
companion object {
private var INSTANCE: CityDatabase? = null
fun getInstance(context: Context): CityDatabase {
return INSTANCE ?: synchronized(this) {
Room.databaseBuilder(
context,
CityDatabase::class.java,
"city.db"
).build()
}.also { INSTANCE = it }
}
}
}
在執行完後,如果後來又想在 table 加入新的欄位,就需要更改 database 的 version,但如果已推上線,有新舊用戶的話就必須 migration 我們的 db:
@Database(entities = [CityEntities::class], version = 2)
abstract class CityDatabase: RoomDatabase() {
abstract fun cityDao(): CityDAO
companion object {
private var INSTANCE: CityDatabase? = null
fun getInstance(context: Context): CityDatabase {
return INSTANCE ?: synchronized(this) {
Room.databaseBuilder(
context,
CityDatabase::class.java,
"stylish_database"
).addMigrations(MIGRATION_1_2).build()
}.also { INSTANCE = it }
}
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE cityTable ADD COLUMN cityIcon int DEFAULT 0")
}
}
}
}
可以透過 db 取得建立好的 DAO 方法
CityDatabase.getInstance(context).cityDao().getAll()