使用 Room (Android Jetpack 的一部分) 將資料儲存在本機資料庫。
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
如果應用程式可以處理大量結構化資料,將可以在本機保存資料。最常見的用途是快取相關資料片段,這樣即使裝置無法存取網路,使用者仍可在離線時瀏覽這類內容。
Room 持續性資料庫透過 SQLite 提供抽象層,可讓資料庫順暢存取,同時充分發揮 SQLite 的效用。特別是,Room 具有下列優點:
- 提供 SQL 查詢的編譯時間驗證。
- 盡可能減少重複且容易出錯的樣板程式碼的便利註解。
- 簡化資料庫遷移路徑。
基於以上考量,我們強烈建議您使用 Room,而非直接使用 SQLite API。
設定
如要在應用程式中使用 Room,請在應用程式的 build.gradle
檔案中新增下列依附元件。
dependencies { val room_version = "2.7.1" implementation("androidx.room:room-runtime:$room_version") // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP) // See Add the KSP plugin to your project ksp("androidx.room:room-compiler:$room_version") // If this project only uses Java source, use the Java annotationProcessor // No additional plugins are necessary annotationProcessor("androidx.room:room-compiler:$room_version") // optional - Kotlin Extensions and Coroutines support for Room implementation("androidx.room:room-ktx:$room_version") // optional - RxJava2 support for Room implementation("androidx.room:room-rxjava2:$room_version") // optional - RxJava3 support for Room implementation("androidx.room:room-rxjava3:$room_version") // optional - Guava support for Room, including Optional and ListenableFuture implementation("androidx.room:room-guava:$room_version") // optional - Test helpers testImplementation("androidx.room:room-testing:$room_version") // optional - Paging 3 Integration implementation("androidx.room:room-paging:$room_version") }
dependencies { def room_version = "2.7.1" implementation "androidx.room:room-runtime:$room_version" // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP) // See KSP Quickstart to add KSP to your build ksp "androidx.room:room-compiler:$room_version" // If this project only uses Java source, use the Java annotationProcessor // No additional plugins are necessary annotationProcessor "androidx.room:room-compiler:$room_version" // optional - RxJava2 support for Room implementation "androidx.room:room-rxjava2:$room_version" // optional - RxJava3 support for Room implementation "androidx.room:room-rxjava3:$room_version" // optional - Guava support for Room, including Optional and ListenableFuture implementation "androidx.room:room-guava:$room_version" // optional - Test helpers testImplementation "androidx.room:room-testing:$room_version" // optional - Paging 3 Integration implementation "androidx.room:room-paging:$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? )
@Entity public class User { @PrimaryKey public int uid; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; }
如要進一步瞭解 Room 中的資料實體,請參閱「使用 Room 實體定義資料」。
資料存取物件 (DAO)
以下程式碼定義了名稱為 UserDao
的 DAO。UserDao
提供了可讓其餘應用程式與 user
資料表中資料互動所用的方法。
@Dao interface UserDao { @Query("SELECT * FROM user") fun getAll(): List<User> @Query("SELECT * FROM user WHERE uid IN (:userIds)") fun loadAllByIds(userIds: IntArray): List<User> @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") fun findByName(first: String, last: String): User @Insert fun insertAll(vararg users: User) @Delete fun delete(user: User) }
@Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") User findByName(String first, String last); @Insert void insertAll(User... users); @Delete void 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 }
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
注意: 如果您的應用程式以單一程序執行,則在對 AppDatabase
物件執行個體化時,請遵循單例設計模式。每個 RoomDatabase
執行個體都非常昂貴,但在單一程序中,您通常很少需要存取多個執行個體。
如果您的應用程式在多個程序中執行,請將 enableMultiInstanceInvalidation()
納入資料庫建構工具叫用。如此一來,您在每個程序都有一個 AppDatabase
執行個體時,便可在某個程序中作廢共用資料庫檔案,而此無效變更也會自動套用至其他程序內的 AppDatabase
執行個體。
用量
定義資料實體、DAO 和資料庫物件後,您可以使用以下程式碼建立資料庫例項:
val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).build()
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database-name").build();
接著,您可以使用 AppDatabase
的抽象方法來取得 DAO 例項。反過來,您可以使用 DAO 例項的方法與資料庫互動:
val userDao = db.userDao() val users: List<User> = userDao.getAll()
UserDao userDao = db.userDao(); List<User> users = userDao.getAll();
其他資源
如要進一步瞭解 Room,請參閱下列其他資源:
範例
These samples showcase different architectural approaches to developing Android apps. In its different branches you'll find the same app (a TODO app) implemented with small differences.
In this branch you'll find:
User Interface built with Jetpack Jetcaster is a sample podcast app, built with Jetpack Compose. The goal of the sample is to showcase building with Compose across multiple form factors (mobile, TV, and Wear) and full featured architecture.
To try out this sample app, use the latest Learn how this app was designed and built in the design case study, architecture learning journey and modularization learning journey.
This is the repository for the Now in Android app. It is a work in progress 🚧.
Now in Android is a fully functionalArchitecture
Jetcaster sample 🎙️
Now in Android App