Room은 SQLite 개체 매핑 라이브러리 입니다. 이것을 사용하면 상용구 코드를 피하고 SQLite 테이블 데이터를 자바 객체로 쉽게 변환할 수 있습니다. Room은 SQLite문의 컴파일 시간 확인을 제공하며 RxJava, Flowable, LiveData, Observable을 반환할 수 있습니다.
SQL쿼리와 데이터 객체와의 변환이 자유롭지 못합니다. 쿼리를 통해 필터들을 각각 읽고 하나의 데이터 객체의 생성자로서 대입하기 때문에 상용구 코드들이 많이 사용될 수밖에 없습니다.
데이터베이스 마이그레이션을 SQLite에 비해 쉽게 할 수 있습니다.
Schemark 변경 될 경우 SQL쿼리를 수동으로 업데이트 해야하지만 Room은 쉽게 해결할 수 있습니다.
SQLite은 Java 또는 Kotlin의 객체를 변경하기 위해 상용구 코드(Boiler Plate Code)를 사용해야하지만 Room의 경우 ORM(Object Relational Mapping) 덕분에 상용구 코드 없이 매핑이 가능합니다.
Room의 경우 LiveData와 RxJava를 위한 Observation으로 생성하여 동작할 수 있지만 SQLite는 그렇지 않습니다.
- 데이터베이스 : 데이터베이스는 앱에 저장되어 있는 로컬 데이터에 대한 액세스 포인트를 제공해주는 역할
- DAO(Data Access Object) : DAO는 앱에서 데이터베이스의 데이터를 추가, 삭제, 업데이트 작업을 할 수 있는 메소드를 제공해주는 역할, 그 외에도 다양한 쿼리 사용가능
- Entity : 데이터베이스 내에 존재하는 테이블을 가리킵니다.
데이터베이스 클래스는 데이터베이스와 연관된 DAO 인스턴스 앱에 제공합니다. 이후 앱은 DAO를 통해서 테이블을 가리키는 Entity인스턴스를 가져올 수 있습니다. 그리고 앱에서 Entity 클래스를 이용하여 테이블 내에 데이터를 추가하거나, 데이터를 수정합니다.
Room을 사용하기 위해 다음과 같이 gradle에 작성해주고 동기화 해주세요
plugins {
id 'kotlin-kapt'
}
dependencies {
def roomVersion = "2.4.2"
implementation("androidx.room:room-runtime:$roomVersion")
kapt ("androidx.room:room-compiler:$roomVersion")
}
다음 코드는 Edit text에 문자를 작성하고 버튼을 누르면 해당 문자를 Room을 통해 저장 후 TextView에 출력하는 코드입니다.
데이터 항목과 DAO, 데이터베이스 객체를 정의한 후에는 다음 코드를 사용하여 데이터베이스 인스턴스를 만들 수 있습니다.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,"database-name"
).allowMainThreadQueries()
.build()
binding.result.text=db.todoDao().getAll().toString()
binding.btn.setOnClickListener {
db.todoDao().insert(Todo(binding.edit.text.toString()))
binding.result.text = db.todoDao().getAll().toString()
}
}
}
다음 코드는 데이터베이스를 보유할 AppDatabase 클래스를 정의합니다. AppDatabase는 데이터베이스 구성을 정의하고 영구 데이터에 대한 앱의 기본 액세스 포인트 역할을 합니다.
클래스에는 데이터베이스와 연결된 데이터 항목을 모두 나열하는 entitites 배열이 포함된 @Database 주석을 달아줍니다.
클래스는 RoomDatabase를 확장하는 추상 클래스여야 하빈다.
데이터베이스와 연결된 각 DAO 클래스에서 데이터베이스 클래스는 인수가 0개이고 DAO 클래스의 인스턴스를 반환하는 추상 메서드를 정의해야합니다.
AppDatabase.kt
@Database(entities = [Todo::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun todoDao(): TodoDao
}
@Entity
data class Todo( var title: String
) {
@PrimaryKey(autoGenerate = true) var id: Int =0
}
다음 코드는 TodoDao DAO를 정의합니다. TodoDao 앱의 나머지 부분이 Todo 테이블의 데이터와 상호작용하는 데 사용하는 메서드를 제공합니다.
@Dao
interface TodoDao {
@Query("SELECT * FROM Todo")
fun getAll(): List<Todo>
@Insert
fun insert(todo: Todo)
@Update
fun update(todo: Todo)
@Delete
fun delete(todo: Todo)
}