カテゴリー: Android

【Kotlin】RoomでDB管理をする

はじめに

こんにちは。miyagawaです。ここ3ヶ月ほど案件でKotlinに触れ、色々な書き方や実装の方法などがわかり始めてきました。
今回は普段使用していない『Room』を使ってDB管理をしたいと思います。

Gradleを更新

Gradleファイルに【公式の実装マニュアル】の項目を追記します。
gradle(app)だけでなく、gradle(.)も更新する必要があるので注意が必要です。

Data Classを作成する

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ファイルを作成する

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を一時停止させることができるそうですが、今回はつけずに実行してみます。

RoomDatabaseファイルを作成する

ここでようやくRoomという単語が出てきました。
RoomDatabaseクラスは下の条件を満たさなければなりません。

  • RoomDatabaseを継承した抽象クラスであること
  • Entityのリストをアノテーションの中に列挙されている
  • Daoクラスを返却するabstractメソッドを持つこと
  • @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
                }
            }
        }
    }

    DBを操作してみる

    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

    おすすめ書籍

    miyagawa

    シェア
    執筆者:
    miyagawa

    最近の投稿

    フロントエンドで動画デコレーション&レンダリング

    はじめに 今回は、以下のように…

    2週間 前

    Goのクエリビルダー goqu を使ってみる

    はじめに 最近携わっているとあ…

    4週間 前

    【Xcode15】プライバシーマニフェスト対応に備えて

    はじめに こんにちは、suzu…

    2か月 前

    FSMを使った状態管理をGoで実装する

    はじめに 一般的なアプリケーシ…

    3か月 前