〈kotlin〉Room
Android studioでkotlinを使ってAndroidアプリ作成の勉強中。
データベースSQLiteを簡単に扱うことができるRoomの実装をまとめる。
Roomの構成
Roomは以下3つの主要コンポーネントで構成されている。
データエンティティ | データベースのテーブル |
---|---|
データアクセスオブジェクト(DAO) | データベースを操作するメソッド |
データベースクラス | データベースを保持する |
この3つを順に実装していく。
build.gradle
//Room implementation "androidx.room:room-runtime:2.4.1" //アノテーション kapt "androidx.room:room-compiler:2.4.1"
データエンティティ
@Entity アノテーションを付けたクラスとして定義する。
ここで定義したものがデータベースのテーブル内のカラムになる。
@Entity data class User( @PrimaryKey val id: Int, val firstName: String?, val lastName: String? )
エンティティにはデータベーステーブルの各行を一意に識別するために主キーを含める必要がある。
主キーは@PrimaryKeyのアノテーションをつけて定義する。
autoGenerateをtrueにすることでキーを自動生成することができる。
@PrimaryKey(autoGenerate = true) val id: Int
カラム名はデフォルトでフィールド名が使われるが、
@ColumnInfoアノテーションに記載することで自分で設定できる。
(SQLiteのカラム名は大文字小文字の区別はされない。)
@ColumnInfo(name = "first_name") val firstName: String?
テーブル名はデフォルトでクラス名が使われるが、
@Entity アノテーションに記載することで自分で設定できる。
@Entity(tableName = "users")
データアクセスオブジェクト(DAO)
DAOはインターフェイスとして定義する。
コンパイル時に、Room が定義した DAO の実装を自動的に生成してくれる。
DAO内にはデータベースを操作する(挿入、更新、削除、クエリ)メソッドを定義する。
@Dao interface UserDao { //以下3つはコンビニエンスメソッド @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertAll(vararg users: User) @Delete fun delete(user: User) @Update fun updateUsers(vararg users: User) //以下はクエリメソッド @Query("SELECT * FROM user") fun getAll(): List<User> }
コンビニエンスメソッド
シンプルな挿入、更新、削除はアノテーションをつけるだけで実装できる。
@Insertに指定したonConflictは、
データ挿入や更新時に重複が発生した場合の挙動を指定する。
デフォルトではABORT(トランザクションを中止)になっている。
クエリメソッド
複雑な処理やデータをクエリする場合、
@Queryアノテーションでクエリを記述して定義する。
データベース
@Databaseアノテーションをつけ、RoomDatabase を拡張する抽象クラスとして定義する。
@Databaseアノテーションにはデータベースに関連する全てのエンティティの配列と、
データベースのバージョンを渡す。
クラス内にはデータベースに関連するDAOを、
引数なしでDAO クラスのインスタンスを返す抽象メソッドとして定義する。
@Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
使用方法
データベースのインスタンスは以下のように作成する。
val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).build()
データベースの作成後、データベースの抽象メソッドでDAOのインスタンスを取得し、
これを使用することでデータベース操作ができる。
val userDao = db.userDao() val users: List<User> = userDao.getAll()
注意点
- クエリが UI をブロックしないように、Room はメインスレッドでのデータベース アクセスを許可していない。
- データベースのインスタンスは高コストで通常アプリに1つで良いためシングルトンにする。
このあたりは次のブログで。
続き↓
mtnmr.hatenablog.com
mtnmr.hatenablog.com
参考
Room を使用してローカル データベースにデータを保存する | Android デベロッパー | Android Developers
Room エンティティを使用してデータを定義する | Android デベロッパー | Android Developers
Room DAO を使用してデータにアクセスする | Android デベロッパー | Android Developers