この Codelab は、Android Kotlin の基礎コースの一部です。Codelab を順番に進めていくと、このコースを最大限に活用できます。すべてのコース Codelab は Android Kotlin の基礎 Codelab ランディング ページに掲載されています。
はじめに
ほとんどのアプリでは、ユーザーがアプリを閉じた後も保持する必要があるデータがあります。たとえば、プレイリスト、ゲームアイテムのインベントリ、経費や所得の記録、星座のカタログ、経時的な睡眠データなどを保存する場合があります。通常は、データベースを使用して永続データを保存します。
Room
は、Android Jetpack の一部であるデータベース ライブラリです。Room
は、データベースのセットアップと設定に関する多数の処理を行い、アプリが通常の関数呼び出しを使用してデータベースを操作できるようにします。Room
は、SQLite データベースの上に抽象化レイヤとして組み込まれています。Room
より複雑なクエリの場合は、SQLite モデルに準じたクエリ構文を使用します。
以下の画像は、このコースで推奨されているアーキテクチャ全体における Room
データベースの位置付けを示しています。
前提となる知識
以下について把握しておく必要があります。
- Android アプリの基本的なユーザー インターフェース(UI)の作成
- アクティビティ、フラグメント、ビューを使用する。
- フラグメント間を移動し、Safe Args(Gradle プラグイン)を使用してフラグメント間でデータを渡す。
- モデル、モデル ファクトリ、
LiveData
とそのオブザーバーを表示します。これらのアーキテクチャ コンポーネントのトピックについては、このコースの前半の Codelab で説明します。 - SQL データベースと SQLite 言語に関する基礎知識。概要や復習については、SQLite 入門をご覧ください。
学習内容
Room
データベースを作成し、データを永続化する方法- データベース内のテーブルを定義するデータクラスを作成する方法。
- データ アクセス オブジェクト(DAO)を使用して Kotlin 関数を SQL クエリにマッピングする方法。
- データベースが機能しているかどうかをテストする方法。
演習内容
- 夜間の睡眠データ用のインターフェースを備えた
Room
データベースを作成します。 - 提供されたテストを使用してデータベースをテストします。
この Codelab では、睡眠の質を追跡するアプリのデータベース部分を構築します。アプリはデータベースを使用して、一定期間にわたる睡眠データを保存します。
アプリには、下図に示すように、フラグメントで表される画面が 2 つあります。
左側の最初の画面には、トラッキングを開始および停止するボタンがあります。画面には、ユーザーのすべての睡眠データが表示されます。[消去] ボタンをクリックすると、そのアプリがユーザーのために収集したすべてのデータが完全に削除されます。
右の 2 番目の画面では、睡眠の質の評価を選択しています。このアプリでは、レーティングは数値で表示されます。アプリでは、顔アイコンとそれに対応する数字の両方が表示されます。
ユーザーのフローは次のようになります。
- アプリを開くと、睡眠管理画面が表示されます。
- ユーザーが [開始] ボタンをタップします。これにより、開始時間が記録されて表示されます。[スタート] ボタンが無効になり、[停止] ボタンが有効になります。
- ユーザーが [停止] ボタンをタップします。終了時間を記録し、睡眠の質の画面を表示します。
- ユーザーが睡眠品質のアイコンを選択します。画面が終了し、トラッキング画面に睡眠時間と睡眠品質が表示されます。[停止] ボタンは無効になり、[開始] ボタンは有効になっています。アプリの準備はもう終わりです。
- データベースにデータが格納されている場合は常に、[クリア] ボタンが有効になります。ユーザーが [消去] ボタンをタップしても、すべてのデータが消去されずに消去されます。「よろしいですか?」というメッセージはありません。
このアプリは、完全なアーキテクチャのコンテキストに示すように、簡略化されたアーキテクチャを使用しています。アプリは次のコンポーネントのみを使用します。
- UI コントローラ
- モデルと
LiveData
を表示します - Room データベース
ステップ 1: スターター アプリをダウンロードして実行する
- GitHub から TrackMySleepQuality-Starter アプリをダウンロードします。
- アプリをビルドして実行します。このアプリには
SleepTrackerFragment
フラグメントの UI が表示されますが、データは表示されません。ボタンがタップに反応しない。
ステップ 2: スターター アプリを調べる
- Gradle ファイルを確認します。
- プロジェクトの Gradle ファイル
プロジェクト レベルのbuild.gradle
ファイルで、ライブラリのバージョンを指定する変数を確認します。スターター アプリで使用されているバージョンは連携しており、このアプリでも問題なく機能します。この Codelab を完了すると、Android Studio で一部のバージョンを更新するよう求められる場合があります。アプリ内のバージョンを更新するか、そのまま使用するかは、ユーザーの判断に任されます。コンパイル エラーが発生した場合は、最終ソリューション アプリが使用するライブラリ バージョンの組み合わせをお試しください。 - モジュールの Gradle ファイル。
Room
を含むすべての Android Jetpack ライブラリの依存関係と、コルーチンの依存関係に注目してください。
- パッケージと UI を見てみましょう。アプリは機能によって構成されています。このパッケージにはプレースホルダ ファイルが含まれており、この Codelab 全体を通してコードを追加します。
database
パッケージ(Room
データベースに関連するすべてのコード)sleepquality
およびsleeptracker
パッケージには、各画面のフラグメント、ビューモデル、ビューモデル ファクトリが含まれています。
Util.kt
ファイルには、睡眠の質に関するデータを表示する機能があります。一部のコードは、後で作成するビューモデルを参照するため、コメントアウトされています。- androidTest フォルダ(
SleepDatabaseTest.kt
)を見てみましょう。このテストを使用して、データベースが想定どおりに動作することを確認します。
Android では、データはデータクラスで表されます。そのデータは、関数呼び出しを使用してアクセスおよび変更されます。しかしデータベースの世界では、エンティティとクエリが必要です。
- エンティティは、データベースに保存するオブジェクトまたはコンセプト、およびそのプロパティを表します。エンティティ クラスによってテーブルが定義され、そのクラスの各インスタンスはテーブル内の行を表します。各プロパティは列を定義します。アプリでは、エンティティが睡眠に関する情報を保持します。
- クエリは、データベース テーブルまたはテーブルの組み合わせからのデータまたは情報のリクエスト、またはデータに対してアクションを実行するリクエストです。一般的に、クエリはエンティティの取得、挿入、更新に使用されます。たとえば、記録されているすべての睡眠日を開始時間でクエリできます。
Room
は、Kotlin データクラスから SQLite テーブルに格納できるエンティティ、そして関数の宣言から SQL クエリまで、大変な労力を伴います。
各エンティティはアノテーション付きデータクラスとして定義し、インタラクションはアノテーション付きインターフェースであるデータ アクセス オブジェクト(DAO)として定義する必要があります。Room
は、これらのアノテーション付きクラスを使用して、データベース内のテーブルとデータベースを操作するクエリを作成します。
ステップ 1: SleepNight エンティティを作成する
このタスクでは、1 晩の睡眠をアノテーション付きデータクラスとして定義します。
1 晩の睡眠の場合、開始時間、終了時間、質の高い評価を記録する必要があります。
夜間を一意に識別するには ID も必要になります。
database
パッケージで、SleepNight.kt
ファイルを見つけて開きます。- ID、開始時間(ミリ秒)、終了時間(ミリ秒)、睡眠の質の評価の数値パラメータで
SleepNight
データクラスを作成します。
sleepQuality
を初期化する必要があるため、-1
に設定し、品質データが収集されていないことを示します。- また、終了時間を初期化する必要もあります。これを開始時刻に設定して、終了時刻がまだ記録されていないことを示します。
data class SleepNight(
var nightId: Long = 0L,
val startTimeMilli: Long = System.currentTimeMillis(),
var endTimeMilli: Long = startTimeMilli,
var sleepQuality: Int = -1
)
- クラス宣言の前に、データクラスに
@Entity
アノテーションを付けます。テーブルにdaily_sleep_quality_table
という名前を付けます。tableName
の引数は省略可能ですが、指定することをおすすめします。ドキュメント内で他の引数を検索することもできます。
プロンプトが表示されたら、Entity
と他のすべてのアノテーションをandroidx
ライブラリからインポートします。
@Entity(tableName = "daily_sleep_quality_table")
data class SleepNight(...)
nightId
を主キーとして識別するには、nightId
プロパティに@PrimaryKey
アノテーションを付けます。Room
が各エンティティの ID を生成するように、パラメータautoGenerate
をtrue
に設定します。これにより、各晩の ID が一意になります。
@PrimaryKey(autoGenerate = true)
var nightId: Long = 0L,...
- 残りのプロパティに
@ColumnInfo
アノテーションを付けます。次のように、パラメータを使用してプロパティ名をカスタマイズします。
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "daily_sleep_quality_table")
data class SleepNight(
@PrimaryKey(autoGenerate = true)
var nightId: Long = 0L,
@ColumnInfo(name = "start_time_milli")
val startTimeMilli: Long = System.currentTimeMillis(),
@ColumnInfo(name = "end_time_milli")
var endTimeMilli: Long = startTimeMilli,
@ColumnInfo(name = "quality_rating")
var sleepQuality: Int = -1
)
- コードをビルドして実行し、エラーがないことを確認します。
このタスクでは、データアクセス オブジェクト(DAO)を定義します。Android では、DAO はデータベースの挿入、削除、更新を行うための便利なメソッドを提供します。
Room
データベースを使用する場合は、コード内で Kotlin 関数を定義して呼び出し、データベースを照会します。これらの Kotlin 関数は、SQL クエリにマッピングされています。DAO でアノテーションを使用してこれらのマッピングを定義すると、Room
で必要なコードが作成されます。
DAO は、データベースにアクセスするためのカスタム インターフェースを定義するものと考えることができます。
一般的なデータベース操作の場合、Room
ライブラリには @Insert
、@Delete
、@Update
などの便利なアノテーションが用意されています。それ以外の場合は、@Query
アノテーションがあります。SQLite でサポートされている、あらゆるクエリを記述できます。
さらに、Android Studio でクエリを作成すると、コンパイラが SQL クエリの構文エラーをチェックします。
睡眠の睡眠のデータを追跡するデータベースの場合、次のことができる必要があります。
- 新しい夜を挿入します。
- 既存の夜を更新して、終了時間と品質評価を更新します。
- キーに基づいて特定の宿泊日を取得します。
- すべての晩を取得して表示できるようにする。
- 最新の睡眠情報を確認。
- データベース内のすべてのエントリを削除します。
ステップ 1: SleepDatabase DAO を作成する
database
パッケージで、SleepDatabaseDao.kt
を開きます。interface
SleepDatabaseDao
には@Dao
アノテーションが付けられています。すべての DAO には@Dao
キーワードでアノテーションを付ける必要がある。
@Dao
interface SleepDatabaseDao {}
- インターフェースの本文内に
@Insert
アノテーションを追加します。@Insert
の下に、Entity
クラスのSleepNight
のインスタンスを引数として取るinsert()
関数を追加します。
そのとおりです。Room
は、SleepNight
をデータベースに挿入するために必要なすべてのコードを生成します。Kotlin コードからinsert()
を呼び出すと、Room
が SQL クエリを実行し、エンティティをデータベースに挿入します。(注: この関数には任意の名前を付けることができます)。
@Insert
fun insert(night: SleepNight)
- 1 つの
SleepNight
用にupdate()
関数と@Update
アノテーションを追加します。更新されたエンティティは、渡されたエンティティと同じキーを持つエンティティです。エンティティの他のプロパティの一部またはすべてを更新できます。
@Update
fun update(night: SleepNight)
残りの機能には便利なアノテーションがないため、@Query
アノテーションを使用して SQLite クエリを指定する必要があります。
Long
key
引数を受け取り、null 値許容SleepNight
を返すget()
関数を含む@Query
アノテーションを追加します。パラメータがない場合は、エラーが表示されます。
@Query
fun get(key: Long): SleepNight?
- クエリは文字列パラメータとしてアノテーションとして指定されます。
@Query
にパラメータを追加します。String
を SQLite クエリにします。
daily_sleep_quality_table
からすべての列を選択します。WHERE
句でnightId
を :key
引数と一致させます。:key
に注目してください。クエリ内でコロン表記を使用して、関数内の引数を参照しています。
("SELECT * from daily_sleep_quality_table WHERE nightId = :key")
clear()
関数と SQLite クエリを使用して別の@Query
をdaily_sleep_quality_table
からDELETE
にすべて追加します。このクエリではテーブル自体は削除されません。@Delete
アノテーションは 1 つのアイテムを削除します。そして、@Delete
を使用して削除する宿泊のリストを指定できます。デメリットは、テーブル内の情報をフェッチまたは把握する必要があることです。@Delete
アノテーションは特定のエントリを削除するのには適していますが、テーブルからすべてのエントリを消去する場合には効率的ではありません。
@Query("DELETE FROM daily_sleep_quality_table")
fun clear()
getTonight()
関数に@Query
を追加します。getTonight()
によって返されるSleepNight
を null 値許容にし、関数がテーブルが空の場合に対応できるようにします。(テーブルは最初とデータが消去された後に空になります)。
データベースから「tonight」を取得するには、nightId
で並べ替えられた結果のリストの最初の要素を、降順で表示する SQLite クエリを記述します。要素を 1 つだけ返すには、LIMIT 1
を使用します。
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC LIMIT 1")
fun getTonight(): SleepNight?
@Query
とgetAllNights()
関数を追加します。
- SQLite クエリが
daily_sleep_quality_table
からのすべての列を降順で返すようにします。 getAllNights()
がSleepNight
エンティティのリストをLiveData
として返すようにします。Room
がこのLiveData
を最新の状態に維持します。つまり、データを明示的に取得する必要があるのは一度だけです。- 場合によっては、
androidx.lifecycle.LiveData
からLiveData
をインポートする必要があります。
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC")
fun getAllNights(): LiveData<List<SleepNight>>
- 目に見える変化はありませんが、アプリを実行してエラーがないことを確認します。
このタスクでは、前のタスクで作成した Entity
と DAO を使用する Room
データベースを作成します。
@Database
アノテーションを付けた抽象データベース ホルダー クラスを作成する必要があります。このクラスには、データベースが存在しない場合にデータベースのインスタンスを作成するか、既存のデータベースへの参照を返すメソッドが 1 つあります。
Room
データベースの取得は少し複雑になります。そのため、コードを開始する前に一般的なプロセスは次のとおりです。
extends RoomDatabase
を作成するpublic abstract
クラスを作成します。このクラスはデータベース ホルダーとして機能します。Room
が実装を作成するため、このクラスは抽象クラスです。- クラスに
@Database
アノテーションを付けます。引数で、データベースのエンティティを宣言し、バージョン番号を設定します。 companion
オブジェクト内で、SleepDatabaseDao
を返す抽象メソッドまたはプロパティを定義します。Room
が本文を生成します。- アプリ全体で必要な
Room
データベースのインスタンスは 1 つだけなので、RoomDatabase
をシングルトンにします。 Room
のデータベース ビルダーを使用して、データベースが存在しない場合にのみデータベースを作成します。それ以外の場合は、既存のデータベースを返します。
ステップ 1: データベースを作成する
database
パッケージで、SleepDatabase.kt
を開きます。- このファイルで、
RoomDatabase
を拡張するSleepDatabase
という名前のabstract
クラスを作成します。
クラスに@Database
アノテーションを付けます。
@Database()
abstract class SleepDatabase : RoomDatabase() {}
- エンティティとバージョン パラメータが欠落していると、エラーが表示されます。
Room
がデータベースを構築できるように、@Database
アノテーションには複数の引数が必要です。
entities
のリストを持つ唯一のアイテムとしてSleepNight
を指定します。version
を1
に設定します。スキーマを変更するたびに、バージョン番号を増やす必要があります。- スキーマのバージョン履歴のバックアップを保持しないように、
exportSchema
をfalse
に設定します。
entities = [SleepNight::class], version = 1, exportSchema = false
- データベースは DAO について知る必要があります。クラスの本文内で、
SleepDatabaseDao
を返す抽象値を宣言します。複数の DAO を持つことができます。
abstract val sleepDatabaseDao: SleepDatabaseDao
- その下で、
companion
オブジェクトを定義します。コンパニオン オブジェクトを使用すると、クライアントはクラスをインスタンス化せずにデータベースを作成または取得するためのメソッドにアクセスできます。このクラスはデータベースを提供するだけであるため、インスタンス化する理由はありません。
companion object {}
companion
オブジェクト内で、データベース用に null 許容のプライベート変数INSTANCE
を宣言し、null
に初期化します。INSTANCE
変数は、データベースが作成されるとデータベースへの参照を保持します。これにより、コストのかかるデータベースへの接続を繰り返し開く必要がなくなります。
INSTANCE
に @Volatile
アノテーションを付けます。volatile 変数の値はキャッシュに保存されません。書き込みと読み取りはすべてメインメモリとの間で行われます。これにより、INSTANCE
の値が常に最新になり、すべての実行スレッドで同じになります。これは、あるスレッドが INSTANCE
に加えた変更が、すぐに他のすべてのスレッドに反映されることを意味します。たとえば、2 つのスレッドのそれぞれがキャッシュ内の同じエンティティを更新する場合は、問題が発生しません。
@Volatile
private var INSTANCE: SleepDatabase? = null
INSTANCE
の下、companion
オブジェクト内で、データベース ビルダーに必要なContext
パラメータを含むgetInstance()
メソッドを定義します。SleepDatabase
型を返します。getInstance()
はまだ何も返していないため、エラーが表示されます。
fun getInstance(context: Context): SleepDatabase {}
getInstance()
内にsynchronized{}
ブロックを追加します。コンテキストにアクセスできるように、this
を渡します。
複数のスレッドが同時にデータベース インスタンスを要求し、結果的に 1 つではなく 2 つのデータベースが作成される可能性があります。このサンプルアプリでは、発生する可能性は低いですが、より複雑なアプリで発生する可能性があります。コードをsynchronized
にラップするコードをラップすると、一度に 1 つのスレッドのみがこのコードブロックに入ることができ、データベースは一度だけ初期化されます。
synchronized(this) {}
- 同期ブロック内で、
INSTANCE
の現在の値をローカル変数instance
にコピーします。これは、ローカル変数でのみ利用可能なスマート キャストを利用するためです。
var instance = INSTANCE
synchronized
ブロック内の、synchronized
ブロックの最後にあるreturn instance
。戻り値の型不一致エラーは無視します。完了すると、null は返されません。
return instance
return
ステートメントの上にif
ステートメントを追加して、instance
が null である(つまり、まだデータベースが存在しない)かどうかを確認します。
if (instance == null) {}
instance
がnull
の場合は、データベース ビルダーを使用してデータベースを取得します。if
ステートメントの本文で、Room.databaseBuilder
を呼び出して、渡されたコンテキスト、データベース クラス、データベースの名前(sleep_history_database
)を指定します。エラーを解消するには、次の手順で移行戦略とbuild()
を追加する必要があります。
instance = Room.databaseBuilder(
context.applicationContext,
SleepDatabase::class.java,
"sleep_history_database")
- 必要な移行戦略をビルダーに追加します。
.fallbackToDestructiveMigration()
を使用します。
通常、スキーマが変更されたときの移行戦略を移行オブジェクトに指定する必要があります。移行オブジェクトは、データが失われないように、古いスキーマの行をすべて取得して新しいスキーマの行に変換する方法を定義するオブジェクトです。移行は、この Codelab の対象外です。簡単なソリューションは、データベースを破棄して再構築することです。つまりデータは失われます。
.fallbackToDestructiveMigration()
- 最後に、
.build()
を呼び出します。
.build()
if
ステートメント内の最後のステップとして、INSTANCE = instance
を割り当てます。
INSTANCE = instance
- 最終的なコードは次のようになります。
@Database(entities = [SleepNight::class], version = 1, exportSchema = false)
abstract class SleepDatabase : RoomDatabase() {
abstract val sleepDatabaseDao: SleepDatabaseDao
companion object {
@Volatile
private var INSTANCE: SleepDatabase? = null
fun getInstance(context: Context): SleepDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
SleepDatabase::class.java,
"sleep_history_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
- コードをビルドして実行します。
これで、Room
データベースを使用するためのすべての構成要素ができました。このコードはコンパイルされて実行されますが、実際に機能するかどうかを確認する方法はありません。基本的なテストを追加してみましょう。
ステップ 2: SleepDatabase をテストする
このステップでは、提供されているテストを実行して、データベースが機能することを確認します。これにより、データベースを構築する前にデータベースが動作していることを確認できます。提供されているテストは基本的です。本番環境アプリでは、すべての DAO ですべての機能とクエリを実行します。
スターター アプリには androidTest フォルダがあります。この androidTest フォルダには、Android インストゥルメンテーションに関する単体テストが含まれています。これは、テストに Android フレームワークが必要であるため、実機または仮想デバイスでテストを実行する必要があるということです。もちろん、Android フレームワークを必要としない純粋な単体テストを作成して実施することもできます。
- Android Studio の androidTest フォルダで、SleepDatabaseTest ファイルを開きます。
- コードのコメントを外すには、コメント付きのコードをすべて選択し、
Cmd+/
またはControl+/
のキーボード ショートカットを押します。 - ファイルを確認します。
ここでは、再利用できるもう一つのコードについて、テストコードを簡単にご紹介します。
SleepDabaseTest
はテストクラスです。@RunWith
アノテーションはテストランナー(テストを設定して実行するプログラム)を識別します。- 設定中に、
@Before
アノテーションが付いた関数が実行され、SleepDatabaseDao
を使用してメモリ内SleepDatabase
が作成されます。「メモリ内」とは、このデータベースがファイル システムに保存されず、テストの実行後に削除されることを意味します。 - また、メモリ内データベースをビルドする際、このコードは別のテスト固有のメソッド
allowMainThreadQueries
を呼び出します。デフォルトでは、メインスレッドでクエリを実行しようとすると、エラーが発生します。このメソッドにより、テスト中にのみ実施する必要があるメインスレッドでテストを実行できます。 @Test
アノテーション付きのテストメソッドで、SleepNight
を作成、挿入、取得し、それらが同じであることのアサーションを行います。問題が発生した場合は、例外をスローします。実際のテストでは、複数の@Test
メソッドを使用します。- テストが完了すると、
@After
アノテーションが付いた関数によってデータベースが閉じられます。
- [Project] ペインでテストファイルを右クリックし、[Run 'SleepDatabaseTest'] を選択します。
- テストの実行後、[SleepDatabaseTest] ペインですべてのテストに合格していることを確認します。
すべてのテストに合格しているため、次のことを理解できました。
- データベースは正しく作成されます。
SleepNight
をデータベースに挿入できます。SleepNight
を取り戻せます。SleepNight
は品質に対して正しい値である。
Android Studio プロジェクト: TrackMySleepQualityRoomAndTesting
データベースをテストするときは、DAO で定義されているすべてのメソッドを実行する必要があります。テストを完了するには、テストを追加して実行し、他の DAO メソッドを実行してください。
- テーブルを、
@Entity
アノテーション付きのデータクラスとして定義する。@ColumnInfo
アノテーション付きのプロパティを、テーブルの列として定義する。 - データ アクセス オブジェクト(DAO)を、
@Dao
アノテーション付きのインターフェースとして定義する。DAO は、Kotlin 関数をデータベース クエリにマッピングする。 - アノテーションを使用して、
@Insert
、@Delete
、@Update
関数を定義する。 - SQLite クエリ文字列の
@Query
アノテーションを他のクエリのパラメータとして使用する。 - データベースを返す
getInstance()
関数を含む抽象クラスを作成します。 - インストルメンテーション テストを使用して、データベースと DAO が期待どおりに動作していることを確認します。提供されているテストをテンプレートとして使用できます。
Udacity コース:
Android デベロッパー向けドキュメント:
RoomDatabase
Database
(アノテーション)Room
で、未加工のクエリを使用できます。Roomdatabase.Builder
- トレーニングのテスト
SQLiteDatabase
クラスDao
Room
永続ライブラリ
その他のドキュメントと記事:
- シングルトン パターン
- Google Developer Experts から: Volatile と Sync を適切に使用して正常に同期している
- コンパニオン オブジェクト
- Room による移行について
- Room による移行のテスト
- データベースの履歴
- SQLite ウェブサイト
- SQLite が理解できる SQL の完全な説明
このセクションでは、インストラクターが主導するコースの一環として、この Codelab に取り組む生徒の課題について説明します。教師は以下のことを行えます。
- 必要に応じて課題を割り当てます。
- 宿題の提出方法を生徒に伝える。
- 宿題を採点します。
教師はこれらの提案を少しだけ使うことができます。また、他の課題は自由に割り当ててください。
この Codelab にご自分で取り組む場合は、これらの課題を使用して知識をテストしてください。
次の質問に答えてください。
問題 1
クラスが Room
データベースに保存するエンティティであることを示すにはどうすればよいでしょうか。
- クラスを
DatabaseEntity
に拡張します。 - クラスに
@Entity
アノテーションを付けます。 - クラスに
@Database
アノテーションを付けます。 - クラスを
RoomEntity
に拡張し、さらに@Room
アノテーションを付けます。
質問 2
DAO(データアクセス オブジェクト)は、Room
が Kotlin 関数をデータベース クエリにマッピングするために使用するインターフェースです。
インターフェースが Room
データベースの DAO を表すことを示すにはどうすればよいでしょうか。
- インターフェースを
RoomDAO
に拡張します。 - インターフェースを
EntityDao
に拡張して、DaoConnection()
メソッドを実装します。 - インターフェースに
@Dao
アノテーションを付けます。 - インターフェースに
@RoomConnection
アノテーションを付けます。
問題 3
Room
データベースの説明として正しいものは次のうちどれですか。該当するものをすべて選択してください。
Room
データベースのテーブルは、アノテーション付きデータクラスとして定義できます。- クエリから
LiveData
を返す場合は、LiveData
が変更されてもRoom
によってLiveData
が最新の状態に保たれます。 - 各
Room
データベースには DAO が 1 つだけ必要です。 - クラスを
Room
データベースとして識別するには、RoomDatabase
のサブクラスにして@Database
アノテーションを付けます。
問題 4
@Dao
インターフェースで使用できるアノテーションは次のうちどれですか。該当するものをすべて選択してください。
@Get
@Update
@Insert
@Query
問題 5
データベースが機能していることを確認するには、どうすればよいですか。該当するものをすべて選択してください。
- インストルメンテーション テストを作成する。
- データが表示されるまでアプリの書き込みと実行を続けます。
- DAO インターフェースのメソッドの呼び出しを、
Entity
クラスの同等のメソッドの呼び出しに置き換えます。 Room
ライブラリで提供されるverifyDatabase()
関数を実行します。
次のレッスン「
このコースの他の Codelab へのリンクについては、Android Kotlin の基礎 Codelab ランディング ページをご覧ください。