使用 Room (Android Jetpack 的一部分)將資料儲存在本機資料庫。
如果應用程式可以處理大量結構化資料,將可以在本機保存資料。最常見的用途是快取相關資料片段,這樣即使裝置無法存取網路,使用者仍可在離線時瀏覽這類內容。
Room 永久保存程式庫透過 SQLite 提供抽象層,可讓資料庫順暢存取,同時充分發揮 SQLite 的效用。特別是,Room 具有下列優點:
- 提供 SQL 查詢的編譯時間驗證。
- 盡可能減少重複且容易出錯的樣板程式碼的便利註解。
- 簡化資料庫遷移路徑。
建議您使用 Room,而不要直接使用 SQLite API。
設定
如要在應用程式中使用 Room,請在模組的 build.gradle.kts 檔案中新增下列依附元件。Room 3.0 需要 KSP 進行註解處理。
Kotlin
dependencies { val room_version = "3.0.0" implementation("androidx.room3:room3-runtime:$room_version") ksp("androidx.room3:room3-compiler:$room_version") }
Groovy
dependencies { def room_version = "3.0.0" implementation "androidx.room3:room3-runtime:$room_version" ksp "androidx.room3:room3-compiler:$room_version" }
主要元件
Room 有三個主要元件:
- 資料庫類別,用於保存資料庫並做為應用程式保留資料基礎連線的主要存取點。
- 代表應用程式資料庫中資料表的資料實體。
- 資料存取物件 (DAO),提供應用程式可用於查詢、更新、插入及刪除資料庫中資料的函式。
資料庫類別可為您的應用程式提供與該資料庫關聯的 DAO 執行個體。反過來,應用程式可以使用 DAO 來擷取資料庫中的資料,做為關聯資料實體物件的執行個體。應用程式也可以使用定義的資料實體,更新對應資料表中的資料列,或是建立新的資料列來插入資料。圖 1 說明 Room 不同元件之間的關係。
實作範例
本節說明採用單一資料實體和單一 DAO 的 Room 資料庫實作範例。
資料實體
以下程式碼定義 User 資料實體。每個 User 執行個體都代表應用程式資料庫中 user 資料表的一個資料列。
@Entity data class User( @PrimaryKey val uid: Int, @ColumnInfo(name = "first_name") val firstName: String, @ColumnInfo(name = "last_name") val lastName: String )
如要進一步瞭解 Room 中的資料實體,請參閱「使用 Room 實體定義資料」。
資料存取物件 (DAO)
以下程式碼定義了名為 UserDao 的 DAO。UserDao 提供應用程式其餘部分與 user 資料表中的資料互動所用的函式。
@Dao interface UserDao { @Query("SELECT * FROM user") suspend fun getAll(): List<User> @Query("SELECT * FROM user WHERE uid IN (:userIds)") suspend fun loadAllByIds(userIds: IntArray): List<User> @Query( """ SELECT * FROM user WHERE first_name LIKE :first AND last_name LIKE :last LIMIT 1 """ ) suspend fun findByName(first: String, last: String): User @Insert suspend fun insertAll(vararg users: User) @Delete suspend fun delete(user: User) }
如要進一步瞭解 DAO,請參閱「使用 Room DAO 存取資料」。
資料庫
以下程式碼定義了用於保存資料庫的 AppDatabase 類別。AppDatabase 定義了資料庫設定,並做為應用程式保留資料的主要存取點。資料庫類別必須符合下列條件:
- 必須使用
@Database註解來備註類別,其中包含entities陣列,列出了與資料庫關聯的所有資料實體。 - 類別必須是擴充
RoomDatabase的抽象類別。 - 針對與資料庫相關聯的每個 DAO 類別,資料庫類別必須定義不使用引數的抽象函式,並傳回 DAO 類別的例項。
@Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
注意: 如果您的應用程式以單一程序執行,則在對 AppDatabase 物件執行個體化時,請遵循單例設計模式。每個 RoomDatabase 執行個體都非常昂貴,但在單一程序中,您通常很少需要存取多個執行個體。
如果您的應用程式在多個程序中執行,請將 enableMultiInstanceInvalidation() 納入資料庫建構工具叫用。如此一來,您在每個程序都有一個 AppDatabase 執行個體時,便可在某個程序中作廢共用資料庫檔案,而此無效變更也會自動套用至其他程序內的 AppDatabase 執行個體。
用量
定義資料實體、DAO 和資料庫物件後,您可以使用以下程式碼建立資料庫執行個體:
val db = Room.databaseBuilder<AppDatabase>(applicationContext, "database-name") .setDriver(AndroidSQLiteDriver()) .build()
接著,您可以使用 AppDatabase 的抽象函式來取得 DAO 執行個體。反過來,您可以使用 DAO 執行個體的函式與資料庫互動:
val userDao = db.userDao() val users: List<User> = userDao.getAll()
其他資源
如要進一步瞭解 Room,請參閱下列其他資源: