#50 AndroidでToDoアプリを作る - データ定義とデータベース
今回は、ToDoアプリで扱うデータを定義し、データベースを作ってみます。
ToDoアプリで扱うデータ
画面レイアウト案や、ToDoアプリで実現したい機能をもとに、ToDoアプリで扱うデータの定義をしてみましょう。
今回作るToDoアプリは技術習得用アプリなので、「タイトル」と「詳細」をToDoとして保存できるようにしてみます。また、リスト表示もしたいので、作成日時と更新日時も保存しておくとよさそうです。表にすると、ToDoデータは次の定義になります。
項目名 | 型 | 説明 |
---|---|---|
id | Int | キーとして使う |
title | String | ToDoのタイトル |
detail | String | ToDoの詳細 |
created | Date(Long) | ToDoを作った時刻(Unix Timestamp) |
modified | Date(Long) | ToDoを最後に修正した時刻(Unix Timestamp) |
「ToDoをサーバーに保存するアプリ」を作る場合、サーバー側の事情もあるのでデータ定義はサーバーサイドエンジニアと協力しながら行うことになるでしょう。
他にToDoアプリで必要となるデータがないか検討してみましょう。サーバーとの連携を行うアプリの場合、ログイン中ユーザーの情報などもデータとして定義しておく必要があります。今回作るToDoアプリは、先ほど定義したToDoの定義だけでよさそうです。
Roomの導入
データの定義ができたので、次はアプリ内にデータベースを作ります。AndroidではSQLiteというリレーショナルデータベースを使うことができます。このSQLiteを簡単に扱うため、Jetpack Roomというライブラリが公式で用意されています。
Roomを使うには、app/build.gradleのdependenciesに次の2行を追加します。バージョンは本記事執筆時点での最新バージョンです。
dependencies {
implementation 'androidx.room:room-runtime:2.2.5'
kapt 'androidx.room:room-compiler:2.2.5'
}
kaptを使用しているので、プラグインを追加します。最初から追加されているkotlin-android
より下に記述します。
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' //この行を追加
エンティティを作る
(ここから先の説明は、過去記事の繰り返しになります)
まず、テーブルの1行分のデータを表すクラスを作ります。このようなクラスをエンティティと呼びます。先ほどのデータ定義に従って、ToDoクラスを追加しましょう。model/todoパッケージを作り、その中にいれておくとよいでしょう。
package com.mokelab.mytodo.model.todo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class ToDo(
@PrimaryKey(autoGenerate = true)
val _id: Int = 0,
val title: String,
val detail: String,
val created: Long,
val modified: Long
)
クラスに対し、@Entity
をつけると、Roomは対応するテーブルを自動で作ってくれます。また、各プロパティがテーブルの列になります。@PrimaryKey
をつけるとその列が主キーになります。今回はIDを主キーにしたいので、_id
プロパティに@PrimaryKey
を付けます。
DAOを作る
次に、ToDoテーブルを操作するためのDAO(Data Access Object)定義を作ります。Roomでは次のようにインターフェースで定義します。
package com.mokelab.mytodo.model.todo
import androidx.room.*
import kotlinx.coroutines.flow.Flow
@Dao
interface ToDoDAO {
@Query("select * from ToDo where created < :startCreated order by created desc limit :limit")
fun getWithCreated(startCreated: Long, limit: Int): Flow<List<ToDo>>
@Insert
suspend fun create(todo: ToDo)
@Update
suspend fun update(todo: ToDo)
@Delete
suspend fun delete(todo: ToDo)
}
追加・更新・削除は、引数にToDoを受け取るメソッドを定義し、対応するアノテーションを付けます。データの取得は、@Query
アノテーションの中にSQLを書きます。今回は、「作成日時が指定したもの未満で、上位n件を取ってくる」ものにしてみました。
SQL中の:で始まるパラメータ(今回はstartCreated
とlimit
)は、メソッドの引数で渡された値に置き換えられて実行されます。戻り値の型をKotlinコルーチンのFlow<T>
にすることで、データベースの監視機能がつきます。
データベースを作る
SQLiteではデータベースをファイルで保存しています。 1つのデータベースには複数のテーブルが入っているので、どのテーブルが入っているかを記述してあげる必要があります。 Roomでは次のような抽象クラスを定義します。
package com.mokelab.mytodo.model.todo
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [ToDo::class], version = 1)
abstract class ToDoDatabase: RoomDatabase() {
abstract fun todoDAO(): ToDoDAO
}
RoomDatabase
を継承したクラスを作ります。そして@Database
アノテーションを付けます。
アノテーションの引数には、ファイルにどのテーブル(エンティティ)を含めるかをentities
で指定し、データベースのバージョンを
version
で指定します。
まとめ
ToDoアプリで使うデータの定義と、Roomを使ったデータベース作成までをやってみました。データ定義は一度アプリをリリースすると、あとから変更するのに手間がかかります。必要な項目は何か、よく検討しながら行いましょう。