hilt 없는 그냥 버전
gradle 설정
//plugins에 id 'kotlin-kapt' 추가 ㅤ //room def roomVersion = "2.4.1" implementation "androidx.room:room-runtime:$roomVersion" kapt "androidx.room:room-compiler:$roomVersion" //코루틴 implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9")
Entity - db table
@Entity data class User( @PrimaryKey(autoGenerate = true) var id: Int = 0, //0으로 지정하면 1부터 생성되는 듯 var name: String, var age: String, var phone: String ㅤㅤ ㅤ //@SerializedName("color") //val color: String //json 으로 받은 데이터 중 키 값이 color인 데이터가 바로 여기에 들어간다. //따라서 json 키 값과 SerializedName값이 동일 해야함 //gson 어노테이션임 )
DAO - db에 접근할 수 있게 해주는 .. 한마디로 쿼리문들이 들어가있는 인터페이스
기본적으로 insert,delete,update 쿼리는 제공해줌.
좀 더 복잡한 쿼리를 사용하고 싶다면 @Query 어노테이션으로 직접 쿼리문을 만들어 쓴다.
@Insert 쿼리는 primaryKey가 겹칠때 어떻게 삽입할지에 대해 몇가지의 방법이 제공되고 있다.@Dao interface UserDao { //@Insert //fun insert(user: User) ㅤ @Update fun update(user: User) ㅤ //@Delete //fun delete(user: User) ㅤ @Query("SELECT * FROM User") suspend fun selectUser(): List<User> ㅤ @Query("SELECT * FROM User WHERE id = :id") suspend fun selectUser(id: String): User? ㅤ @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insert(entity: User) ㅤ @Query("DELETE FROM User WHERE id = :id") suspend fun deleteUser(id: String) ㅤ // OnConflictStrategy.ABORT 충돌이 발생할 경우 처리 중단 // OnConflictStrategy.FAIL 충돌이 발생할 경우 실패처리 // OnConflictStrategy.IGNORE 충돌이 발생할 경우 무시 // OnConflictStrategy.REPLACE 충돌이 발생할 경우 덮어쓰기 // OnConflictStrategy.ROLLBACK 충돌이 발생할 경우 이전으로 되돌리기 }
Database - 데이터베이스를 보유하고 앱의 영구 데이터와의 기본 연결을 위한 기본 액세스 포인트 역할을 합니다.
db생성은 리소스가 많이 들기 때문에, 싱글톤(딱 하나의 객체만 생성)으로 생성해야한다.@Database(entities = [User::class], version = 1) //entity의 구조가 바뀌면 이 버전을 업데이트 해줘야 한다 abstract class UserDatabase : RoomDatabase() { abstract fun userDao(): UserDao ㅤ companion object { private var INSTANCE: UserDatabase? = null ㅤ //Singleton pattern - companion object내에 작성되었기 때문에, 어디서든 INSTANCE.getInstance로 항상 메모리 주소값이 동일한db를 불러올 수 있다. fun getInstance(context: Context): UserDatabase? { if (INSTANCE == null) { //synchronized : 중복 방지 synchronized(UserDatabase::class) { INSTANCE = Room.databaseBuilder( context.applicationContext, UserDatabase::class.java, "user.db" ) //db 이름 . 다른 db와 중복되면 안됨 .fallbackToDestructiveMigration() //버전 업 할 때 이전 데이터 모두 삭제 .build() } } return INSTANCE!! } ㅤ } }
실제 사용
var newUser = User(name = "20", age = "13", phone = "010-1111-5555") //autoGenerate되는 id는 작성x ㅤ val db = UserDatabase.getInstance(applicationContext) ㅤ //room작업은 메인쓰레드에서 할 수 없으므로 코루틴으로 비동기로 실행한다. lifecycleScope.launch { db!!.userDao().insert(newUser) } ㅤ
database만들 때 버전업 시 예전 데이터 모두 삭제해! 가 아니라 예전 데이터를 이전(migration) 하고 싶다면..