こんにちは。miyagawaです。ここ3ヶ月ほど案件でKotlinに触れ、色々な書き方や実装の方法などがわかり始めてきました。
今回は普段使用していない『Room』を使ってDB管理をしたいと思います。
Gradleファイルに【公式の実装マニュアル】の項目を追記します。
gradle(app)だけでなく、gradle(.)も更新する必要があるので注意が必要です。
DB管理する元となるData Classを作成します。
今回はUserというデータ(ID、名前、性別)を作成します。
性別のクラスは「男性、女性、その他」の3種類のみを設定するため、Enum Classを設定しました。@Entity
アノテーションをつけることによって、このクラスはデータベースに保存されるエンティティであることを表すことができます。
@Entity(tableName = "users") // usersというテーブルのデータベースであることを表す data class User constructor( @PrimaryKey(autoGenerate = true) // 必ず主キーをつける必要がある val id: Int, // 主キー ユーザーID val nickname: String, // ニックネーム val gender: Gender // 性別 ) enum class Gender { // 性別のEnum Class MALE, FEMALE, OTHER }
DAOとはData Access Object
の略で、データをSQLで操作する処理を記載します。
コンパイル時にエラーが起こらないかを検証します。そのため、ランタイムエラーが起きにくくなります。
今回はデータ全件取得、追加、更新、削除のメソッドを追加しました。
@Dao // @DaoアノテーションでDaoであることを表す interface UserDao { @Query("SELECT * from users") // 全件取得のSQLをかく。この時にソートや抽出などもできる。 fun getAllUserData(): LiveData> @Insert(onConflict = OnConflictStrategy.REPLACE) // 追加処理 コンフリクトが起こった時は置き換える fun insert(user: User) @Update fun update(user: User) @Delete fun delete(user: User) }
予想していたよりスッキリかけました。suspend fun
を使うことで、Coroutineを一時停止させることができるそうですが、今回はつけずに実行してみます。
ここでようやくRoomという単語が出てきました。
RoomDatabaseクラスは下の条件を満たさなければなりません。
@Database(entities = arrayOf(User::class), version = 1) // Databaseの内容を@Databaseで設定。UserクラスをDBに保存する。versionはデータの構造に変更があれば番号を上げていきます。 public abstract class UserRoomDatabase: RoomDatabase() { abstract fun userDao(): UserDao // Userデータを取り扱うDAO companion object { @Volatile private var INSTANCE: UserRoomDatabase? = null fun getDatabase(context: Context): UserRoomDatabase { val tempInstance = INSTANCE if (tempInstance != null) { return tempInstance } synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, UserRoomDatabase::class.java, "word_database" ).build() INSTANCE = instance return instance } } } }
MainActivityにdatabaseをいじる処理を書きました。
Create、Update、Deleteをメソッド単位で準備し、それぞれonCreateで呼んでいます。
class MainActivity : AppCompatActivity() { companion object { lateinit var database: UserRoomDatabase } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) database = Room.databaseBuilder(this, objectOf(), "kotlin_room_sample.db").build() create() update() delete() } private fun create() { val dao = database.userDao() dao.insert(User(0, "miya-n", Gender.FEMALE)) var userList: List = dao.getAllUserData() } private fun update() { val dao = database.userDao() var userList: List = dao.getAllUserData() dao.update(User(0, "miyagawa", Gender.FEMALE)) userList = dao.getAllUserData() } private fun delete() { val dao = database.userDao() var userList: List = dao.getAllUserData() dao.delete(User(0, "miyagawa", Gender.FEMALE)) userList = dao.getAllUserData() } } internal inline fun objectOf() = T::class.java
Roomを用いてDBを操作しました。LiveDataと連携するとRecycleViewなどに使えて、データが変更されるたびに反映されるのでまた試してみたいと思います。
https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/#0