Room を使用してローカル データベースにデータを保存する Android Jetpack の一部。
比較的大量の構造化データを処理するアプリは、そのデータをローカルに永続化することで大きなメリットを得ることができます。最も一般的なユースケースは、デバイスがネットワークにアクセスできない場合でも、ユーザーがオフラインの間にコンテンツをブラウジングできるように、関連するデータをキャッシュに保存することです。
Room 永続ライブラリは SQLite 全体に抽象化レイヤを提供することで、データベースへのスムーズなアクセスを可能にし、SQLite を最大限に活用できるようにします。特に、Room には次のようなメリットがあります。
- SQL クエリのコンパイル時検証。
- 繰り返しが多く間違いを犯しやすいボイラープレート コードを最小限に抑える便利なアノテーション。
- 効率的なデータベース移行パス。
SQLite API を直接使用するのではなく、Room を使用することをおすすめします。
設定
アプリで 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 は、次の 3 つの主要コンポーネントで構成されます。
- データベース クラス。データベースを保持し、アプリの永続データに対する基礎的な接続のメイン アクセス ポイントとして機能します。
- アプリのデータベースのテーブルを表すデータ エンティティ。
- データ アクセス オブジェクト(DAO)。アプリがデータベースのデータのクエリ、更新、挿入、削除に使用できる関数を提供します。
データベース クラスは、そのデータベースに関連付けられている DAO のインスタンスをアプリに提供します。アプリはこの DAO を使用して、関連するデータ エンティティ オブジェクトのインスタンスとしてデータベースからデータを取得できます。また、定義されたデータ エンティティを使用して、対応するテーブルの行を更新したり、挿入用の新しい行を作成したりできます。図 1 に、Room のさまざまなコンポーネントの関係を示します。

実装例
このセクションでは、1 つのデータ エンティティと 1 つの 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 はデータベース構成を定義し、永続データに対するアプリのメイン アクセス ポイントとして機能します。データベース クラスは次の条件を満たす必要があります。
- クラスには、データベースに関連付けられたすべてのデータ エンティティをリストする
entities配列を含む@Databaseアノテーションを付ける必要があります。 - クラスは、
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 の詳細については、以下の参考情報をご覧ください。