Room 이란?
Room Database 는 Android Jetpack Library 중 하나로 SQL 테이블 데이터에 객체를 매핑시켜주는 DB 라이브러리입니다.
SQLite 를 사용하는 경우 SQLiteOpenHelper 를 상속하는 class 를 만들고 각 column 명을 전역 변수로 지정해놓고 DB 를 구성한 다음 DB에서 데이터를 꺼내올 땐 Cursor 단위로 data 를 꺼내와서 Cursor 를 다시 모델링한 데이터로 매핑시키는..
조금 번잡한 과정을 거쳐야했는데 Room 을 사용할 경우에는 DB 에 저장하려는 데이터 모델에서 column 명을 annotation 을 사용하여 미리 정의하고 Dao(Data Access Object) class 를 사용하여 테이블 생성 작업을 간소화할 수 있습니다.
그럼 이제 사용법을 알아보도록 ..
Data Class
db에서 사용할 데이터 모델을 정의하는 클래스에서 테이블 명과 각 column 명만 작성해주면 되는데
Kotlin 의 data class 기준으로는 아래와 같습니다.
@Entity(tableName = "sample_table")
data class Person(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_id")
var id: Long? = null,
@ColumnInfo(name = "name")
var name: String,
@ColumnInfo(name = "age")
var age: Int
)
여기서 id 를 nullable 객체로 두고 null 값을 설정한 이유는 이렇게 하지 않으면 autoGenerate 옵션이 안먹습니다....
물론 서버에 있는 DB 를 클라이언트에서 올려두고 쓰는 것이고 거기 PrimaryKey 가 이미 존재한다면 그걸 가져다 써도 됩니다.
Dao Interface
아무튼 이제 이 객체를 DB 에서 꺼내고 집어넣는 매개체인 Dao 를 작성해야합니다.
@Dao
interface PersonDao {
@Insert
suspend fun insert(person: Person)
@Insert
suspend fun insertAll(persons: List<Person>)
@Query("SELECT * FROM sample_table")
suspend fun getPersons():List<Person>
@Update
suspend fun update(person: Person)
@Delete
suspend fun delete(person: Person)
@Query("DELETE FROM sample_table")
suspend fun clear()
}
위 코드를 살펴보면 알 수 있듯이
Insert, Update Delete 정도는 어노테이션을 붙이는 것 만으로 그냥 사용할 수 있고
이 외의 작업도 Query 어노테이션 안에 SQL 구문을 넣어서 쉽게 할 수 있습니다.
그리고 suspend function 으로 작성해야 한다는 특징이 있는데 이유는 db 작업이 무거워질 경우 UI thread 가 오랜시간 block되기 때문에 이를 방지하기 위해 suspend function 을 사용하도록 되어있습니다.(dao 를 non-suspend 로 작성하면 컴파일 에러는 나지 않지만 코드를 실행하면 crash 가 발생합니다.)
Database
그럼 Database 를 생성하는 코드도 작성해봅시다.
@Database(entities = [Person::class], version = 1)
abstract class PersonDatabase : RoomDatabase() {
abstract fun personsDao(): PersonDao
companion object {
@Volatile
private var INSTANCE: PersonDatabase? = null
private val LOCK = Any()
fun getDatabase(context: Context): PersonDatabase {
return INSTANCE ?: synchronized(LOCK) {
val instance = Room.databaseBuilder(
context.applicationContext,
PersonDatabase::class.java,
"persons_database"
).build()
INSTANCE = instance
instance
}
}
}
}
추상 클래스로 RoomDatabase 를 상속받은 클래스를 위와 같이 작성한 후
Repository
class MyRepository(context: Context) {
companion object{
private var instance: MyRepository? = null
fun getInstance(context: Context): MyRepository{
if (instance == null){
instance = MyRepository(context)
}
return instance!!
}
}
private val personsDao: PersonDao by lazy {
val database = PersonDatabase.getDatabase(context)
database.personsDao()
}
suspend fun insert(person: Person){
personsDao.insert(person)
}
suspend fun insertAll(persons:List<Person>){
personsDao.insertAll(persons)
}
suspend fun getPersons():List<Person>{
return personsDao.getPersons()
}
suspend fun update(person: Person){
personsDao.update(person)
}
suspend fun delete(person: Person){
personsDao.delete(person)
}
suspend fun clear(){
personsDao.clear()
}
}
이런 식으로 별도의 Repository 클래스를 작성해서 Database 를 불러오며 Dao Interface 도 설정해주면 됩니다.
예시에선 싱글톤 클래스로 작성하였는데 이 부분은 상황에 맞게 사용하면 됩니다.
(저 companion object 블럭의 내용은 필수적이진 않다는 이야기입니다.)
이제 DB 작업을 아래와 같이 할 수 있습니다.
class MainActivity : AppCompatActivity() {
private val mCoroutineScope = CoroutineScope(Dispatchers.IO)
private val mRepository: MyRepository by lazy {
MyRepository.getInstance(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mCoroutineScope.launch {
insertCharles()
}
}
private suspend fun insertCharles(){
val person = Person(name = "김찰스",
age = 28)
insertSomeone(person)
println("${mRepository.getPersons()}")
}
suspend fun insertSomeone(person: Person){
mRepository.insert(person)
}
}
위 예시 코드의 insertSomeone 에 Person 객체를 넣으면 그 Person 이 db에 Insert 되게 됩니다.
즉, Activity 가 시작되면 28세의 김찰스씨가 db 에 insert 되는 것 입니다.
I/System.out: [Person(id=1, name=김찰스, age=28)]
바로 이렇게 말이죠
'Android > Kotlin' 카테고리의 다른 글
Android 배워보자 Compose! (2) (0) | 2024.01.10 |
---|---|
Android 배워보자 Compose - (1) (0) | 2024.01.10 |
Android ExoPlayer 로 앱에서 동영상 재생하기 (1) | 2024.01.05 |
Android Jackson Library 를 이용한 JSON Parsing (1) | 2024.01.05 |
Android 파일 다운로드 받기 (0) | 2024.01.05 |