「Android/kotlin/db/room」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→サンプル) |
(→更新処理) |
||
| 行190: | 行190: | ||
user.name = "siro" | user.name = "siro" | ||
dao.update(user) | dao.update(user) | ||
| + | |||
| + | == | ||
| + | |||
| + | @Insert(onConflict = OnConflictStrategy.ROLLBACK) | ||
| + | @Insert(onConflict = OnConflictStrategy.ABORT) | ||
| + | |||
==参考== | ==参考== | ||
* https://re-engines.com/2019/10/24/%E3%80%90kotlin%E3%80%91room%E3%81%A7db%E7%AE%A1%E7%90%86%E3%82%92%E3%81%99%E3%82%8B/ | * https://re-engines.com/2019/10/24/%E3%80%90kotlin%E3%80%91room%E3%81%A7db%E7%AE%A1%E7%90%86%E3%82%92%E3%81%99%E3%82%8B/ | ||
2020年2月19日 (水) 16:50時点における版
Roomとは
SQLiteのマッパーライブラリ
公式:https://developer.android.com/training/data-storage/room
Androidでも公式が、強くおすすめすると書いてる。
準備
app/build.gradle
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
dependencies {
implementation 'android.arch.persistence.room:runtime:1.0.0'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
kapt 'android.arch.persistence.room:compiler:1.0.0'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
}
サンプル
schema1.usersのテーブルを置く時のサンプル
Schema1Database.kt
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = arrayOf(UserEntity::class), version = 1)
abstract class Schema1Database: RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
@Volatile
private var INSTANCE: Schema1Database? = null
fun getDatabase(context: Context): Schema1Database {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
Schema1Database::class.java,
"schema1.db"
).build()
INSTANCE = instance
return instance
}
}
}
}
UserEntity.kt
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "users")
data class UserEntity constructor(
@PrimaryKey(autoGenerate = true)
val id: Int,
val name: String
)
UserDao.kt
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import androidx.room.Delete
import androidx.room.OnConflictStrategy
@Dao
interface UserDao {
@Query("SELECT * from users")
fun getAll(): List<UserEntity>
@Query("SELECT * FROM users WHERE id IN (:userIds)")
fun loadAllByIds(vararg userIds: Int): List<UserEntity>
@Query("SELECT * FROM users WHERE name LIKE :name")
fun findByLikeName(name: String): UserEntity
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(user: UserEntity)
@Insert
fun insertAll(vararg users: UserEntity)
@Update
fun update(user: UserEntity)
@Update
fun updateUsers(vararg users: UserEntity)
@Delete
fun delete(user: UserEntity)
@Delete
fun deleteUsers(users: List<UserEntity>)
@Query("DELETE FROM users")
fun deleteAll()
}
@Insert(onConflict = OnConflictStrategy.REPLACE) は同一idの場合に置き換えされる
db呼び出し
MainActivity.kt
class MainActivity : AppCompatActivity() {
val scope = CoroutineScope(Dispatchers.Default)
lateinit var db: Schema1Database
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = Schema1Database.getDatabase(applicationContext)
scope.launch {
dbTask()
}
}
private suspend fun dbTask() {
try {
dbExec()
} catch (e: Exception) {
Log.e(localClassName, "onCancelled", e)
}
}
private fun dbExec() {
val dao = db.userDao()
dao.insert(UserEntity(0, "rei"))
dao.insert(UserEntity(1, "taro"))
dao.insert(UserEntity(2, "jiro"))
var users: List<UserEntity> = dao.getAll()
for (user: UserEntity in users) {
Log.i("db", "id=" + user.id.toString() + " name=" + user.name);
}
for (user: UserEntity in users) {
if (user.id == 2) {
Log.i("db", "upd id=" + user.id.toString() +" name=" + user.name);
dao.update(UserEntity(user.id, "siro"))
} else {
Log.i("db", "del id=" + user.id.toString() +" name=" + user.name);
dao.delete(UserEntity(user.id, user.name));
}
}
users = dao.getAll()
for (user: UserEntity in users) {
Log.i("db", "del id=" + user.id.toString() +" name=" + user.name);
dao.delete(UserEntity(user.id, user.name));
}
}
}
出力
2020-01-14 16:16:51.109 24379-24416/? I/db: id=1 name=taro 2020-01-14 16:16:51.109 24379-24416/? I/db: id=2 name=jiro 2020-01-14 16:16:51.109 24379-24416/? I/db: id=21 name=rei 2020-01-14 16:16:51.109 24379-24416/? I/db: del id=1 name=taro 2020-01-14 16:16:51.110 24379-24416/? I/db: upd id=2 name=jiro 2020-01-14 16:16:51.111 24379-24416/? I/db: del id=21 name=rei 2020-01-14 16:16:51.114 24379-24416/? I/db: del id=2 name=siro
idが0のinsertはauto_incrementのmax値が入る?
更新処理
上記例では新規UserEntityを作って入れたが、
dao.update(UserEntity(user.id, "siro"))
変更するプロパティをvalからvarに変えて、更新していれることもできる
UserEntity.kt
data class UserEntity constructor(
@PrimaryKey(autoGenerate = true)
val id: Int,
var name: String
)
user.name = "siro" dao.update(user)
==
@Insert(onConflict = OnConflictStrategy.ROLLBACK) @Insert(onConflict = OnConflictStrategy.ABORT)
参考
- https://re-engines.com/2019/10/24/%E3%80%90kotlin%E3%80%91room%E3%81%A7db%E7%AE%A1%E7%90%86%E3%82%92%E3%81%99%E3%82%8B/
- https://developer.android.com/training/data-storage/room/accessing-data
- https://developer.android.com/training/data-storage/room
- https://qiita.com/niusounds/items/fff5e83489e69d7924fd
- https://android.jlelse.eu/android-room-using-kotlin-f6cc0a05bf23
- https://gabrieltanner.org/blog/android-room
