目的
Googleの公式ライブラリ(だと思う)で、
ローカルにDB設定して永続化や、接続できるライブラリ。
使ってみたメモ
環境
- Android Studio 4.0.1
- Kotlin 1.3.50
参照サイト
developers Room を使用してローカル データベースにデータを保存する
developers Room データベースを移行する
はじめに
ここより以降の記載は私の独断と偏見が混ざっています。
認識ミスもあるかもしれないので、ご了承ください。
参照することで発生した責任については負いませんので、ご了承ください。
Roomについて
今回Roomを使うことになった理由として、携わることになった案件でもともと利用していたから。
それで導入した人もただ使えればいいや感で入れているよう
それで、調査して使ってみたが、ものすごく使いづらい。
Room自体リリースされてそこまで時間経ってないので、これからというトコロがあるらしい。
ただ、今後使いやすくなったとして、いまの利用中のアプリへの影響も結構あると思っていて。
現状、私が新規でアプリを作ることになったとしても利用しないと思う。
AndroidでもRealmを使うと思います。
使いにくいと思った理由は以下
- バックグラウンドスレッドでDB処理しないとエラーになる。(コルーチンオプションを使えば少しは楽!?)
- DBを取り扱うにあたり、3,4クラス(3,4ファイル)も取り扱う必要がある。(Database、Table, DAO, 必要であればConverter)
- マイグレーションがめちゃくちゃ面倒くさい(sqlite文をそのまま記載する必要がある。)
違ったらスミマセン。
対応メモ
公式サイトの記載に+アルファで追記しています。
コンバート設定はプライマリキー、updateなどを記載
ライブラリインストール」
以下でライブラリインストール
appのbuild.gradleに記載する。
dependencies {
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}
DB設定
@Database(entities = arrayOf(User::class), version = 1)
// @TypeConverters(UserConverters::class) sqliteで認識できない型にコンバートする場合
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
テーブル設定
@Entity(primaryKeys = ["uid"])
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "first_name") val firstName: String?,
@ColumnInfo(name = "last_name") val lastName: String?
)
Dao
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): List<User>
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
fun loadAllByIds(userIds: IntArray): List<User>
//insert - updateも対応
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(vararg users: User)
@Delete
fun delete(user: User)
}
コンバート
object UserConverters {
@TypeConverter
fun convertString(value: String?): IntArray? {
//stringをIntArrayに変換する処理
return xxxxx
}
//上記の逆IntArrayからStringに変換する処理も必要であれば
}
マイグレーション
今後のマイグレーションを見込んで
appのbuild.gradleファイルに以下を設定しておいたほうが良いとのこと。
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
}
}
DB読み込み
var database = Room.databaseBuilder(this, AppDatabase::class.java, "AppDatabase").build()
テーブル操作 select
AsyncTask.execute{
val data = database?.userDao()?.getAll()
if (data != null) {
mHandler.post{//メインスレッドで
if (data.isNotEmpty()) {
val name = data[0].firstName
textView.text = name
}
}
}
テーブル操作 insert
val user = User(
1,
"hoge",
"fuga"
)
database?.userDao()?.insert(user)
テーブルclose
if(database != null) {
if(database?.isOpen == true) {
database?.close()
}
database = null
}
マイグレーション操作
Database今回だとAppDatabaseのバージョンを2にする。
テーブルにカラム追加など行う。
Database読み込み時の処理は以下の様にする。
val migration1to2 = object : Migration(1,2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Alter TABLE User ADD COLUMN test text;")
}
}
database = Room.databaseBuilder(this, AppDatabase::class.java, "AppDatabase")
.addMigrations(migration1to2)
.build()
お疲れさまでした。