iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Mobile Development

【Kotlin Notes And JetPack】Build an App系列 第 22

Day 22.【Architecture】Room 的介紹與應用

  • 分享至 

  • xImage
  •  

上一篇在介紹 DataStore 時有提到,如果是較複雜的資料存儲建議使用 Room 來執行,今天就來教紹一下 Room 的操作吧!以下如有解釋不清或是描述錯誤的地方還請大家多多指教:

什麼?

Room 是由 SQLite 提供抽象層,讓我們可以方便取用資料,主要由三個元件組成:

  • Entities:資料儲存的 table
  • DAO ( Data Access Object):提供資料庫寫入、查詢、更新、刪除的方法,將 SQL 的指令包成 function 提供給外部操作
  • DataBase:做為連接 app 資料儲存的主要存取點

如何?

| Set up

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"
}

| Entities

先設計好要存在 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

目前需要寫入顯示及刪除

@Dao
interface CityDAO {
    @Query("SELECT * FROM cityTable")
    fun getAll(): List<CityEntities>

    @Insert
    fun insertAll(vararg users: CityEntities)

    @Delete
    fun delete(user: CityEntities)
}

| Database

建立連線的 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()

Referance

Android Room Official
Android Room Official2


上一篇
Day 21.【Architecture】DataStore 的介紹與應用
下一篇
Day 23.【Architecture】ViewModel 的介紹與應用
系列文
【Kotlin Notes And JetPack】Build an App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言