Android Kotlin Room 示範

撇除簡單的 Key, Value 鍵值對應資料, 在 Android 中要儲存資料最好的方式就是使用 Room ,也就是經過包裝後方便開發的 SQLite

安裝 Room 套件

build.gradle.kts (Module :app)
    
dependencies {
    val room_version = "2.6.1"
    implementation("androidx.room:room-runtime:$room_version")
    annotationProcessor("androidx.room:room-compiler:$room_version")
    ksp("androidx.room:room-compiler:$room_version")
}
    

如果 ksp 出現錯誤,則代表 有點麻煩 ,先不要加上面的 ksp 的那行,等等再補上,比較方便除錯
需要到 build.gradle.kts(Project) 檔案下面加入 com.google.devtools.ksp 這行
    
plugins {
    id("com.android.application") version "8.2.2" apply false
    id("org.jetbrains.kotlin.android") version "1.9.0" apply false
    id("com.google.devtools.ksp") version "1.9.0-1.0.13" apply false
}
    

這裡的 version 很可能和筆者的不一樣,要看上面的 org.jetbrains.kotlin.android 的版本號碼來決定, 然後到 Github google/ksp 的發布頁面 或是 MVN Repository 上找到對應的數字(基本上會一樣,或是像筆者這樣一個區間的 再不能就一個一個試),以筆者目前的專案為例, kotlin 版本是 1.9.0 ,所以就找了 1.9.0-1.0.13 的這個版本,有些發布說明上面有寫對應的 kotlin 版本,所以可能每個都應該要標記只是可能他們忘記了,然後也不用擔心版本選錯,因為選錯會無法執行...

白話文:就是上面的這個數字

回到 build.gradle.kts (Module :app) 的最上面,加入 com.google.devtools.ksp 的第四行:
    
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.devtools.ksp")
}
    

可以執行後再把第五行補上即可。
    
dependencies {
    val room_version = "2.6.1"
    implementation("androidx.room:room-runtime:$room_version")
    annotationProcessor("androidx.room:room-compiler:$room_version")
    ksp("androidx.room:room-compiler:$room_version")
}
    

Room 示範

Room 就是使用 SQLite ,不過這裡不需要寫太多的 SQL 語法,Room 幫我們處理很多了,現在先建立一個資料表的對應物件:
    
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey


@Entity(tableName = "user")
data class UserEntity(
    @PrimaryKey(autoGenerate = true)
    var id: Int,
    @ColumnInfo(name = "name")
    var name: String,
    @ColumnInfo(name = "level")
    var level: Int,
)
    

建立資料存取物件 (DAO),讓我們可以操作資料表
    
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update


@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<UserEntity>

    @Query("SELECT * FROM user WHERE id = :id")
    fun getById(id: Int): UserEntity

    @Query("SELECT * FROM user WHERE name = :name")
    fun getByName(name: String): UserEntity

    @Insert
    fun insert(user: UserEntity)

    @Update
    fun update(user: UserEntity)

    @Delete
    fun delete(user: UserEntity)
}
    

建立資料庫庫定,需要在一開始指定有哪些實體,這裡也簡單的實現了單例模式,方便存取資料庫實例
    
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase

@Database(
    entities = [
        UserEntity::class,
    ], version = 1
)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context,
                    AppDatabase::class.java,
                    "data.db"
                )
                    .build()
                INSTANCE = instance
                instance
            }
        }
    }
}
    

取得資料庫實例
    
val context = LocalContext.current
val db: AppDatabase = AppDatabase.getInstance(context)
    

取得資料:
    
db.userDao().getAll().map {
    Log.i(TAG, "id: ${it.id}, name: ${it.name}, level: ${it.level}")
}
    

新增資料:
    
val entity: UserEntity =
    UserEntity(
        id = 0, // id 會自動遞增
        name = inputName,
        level = level,
    )

db.userDao().insert(entity)
    

更新資料:
    
val entity: UserEntity =
    UserEntity(
        id = 3, // 只要指定 id
    )

db.userDao().update(entity)
    

刪除資料:
    
val entity: UserEntity =
    UserEntity(
        id = 3, // 只要指定 id
    )

db.userDao().delete(entity)
    



參考資料:
Android Developers - Save data in a local database using Room

留言