[Android jetpack 소개] Android jetpack 소개에 이어  jetpack 에서 제공하는 Room 에 대해 알아보고, 기능을 활용해서 간단한 예제를 통해 정리하려고 합니다. 1. Room 소개 기존 안드로이드에서 제공하는 데이터...

[안드로이드] Android jetpack room 예제 : Todo - (1)

 


[Android jetpack 소개]

Android jetpack 소개에 이어 

jetpack 에서 제공하는 Room 에 대해 알아보고,

기능을 활용해서 간단한 예제를 통해 정리하려고 합니다.




1. Room 소개

기존 안드로이드에서 제공하는 데이터베이스 SQLite 에서 

오류에 대한 안정성과 원활하게 데이터베이스에 접근할 수 있는 jetpack 라이브러리입니다. 

안드로이드 공식문서에서도 SQLite 보다 Room 사용을 적극적으로 권장하고있습니다.




2. Room 특징

Room에는 다음과 같은 세 가지 주요 구성요소가 있습니다.

 ▶ DataBase : 데이터베이스 홀더를 포함하며 앱의 지속적인 관계형 데이터의 기본 연결을 위한 기본 액세스 포인트 역할을 합니다. 

 ▶ Entity : 데이터베이스 내의 테이블을 나타냅니다.

 ▶ Dao : 데이터베이스에 액세스하는 데 사용되는 메서드가 포함되어 있습니다.


앱은 Room 데이터베이스를 사용하여 데이터베이스와 연결된 데이터 액세스 개체 또는 DAO를 가져옵니다. 그런 다음 앱은 각 DAO를 사용하여 데이터베이스에서 항목을 가져오고 항목의 변경사항을 다시 데이터베이스에 저장합니다. 마지막으로 앱은 항목을 사용하여 데이터베이스 내의 테이블 열에 해당하는 값을 가져오고 설정합니다.




3. Room 활용

Room 을 활용하여 매일 할일(Todo)을 저장하는 예제를 살펴보겠습니다.



♣ Dependency

room 을 사용하기 위해 gradle 에 아래와 같이 추가해줍니다.
추가로 jetpack 라이브러리를 최대한 사용해 보려합니다.

 - ktx : kotlin 코드를 간결하게 작성할 수 있도록 추가

 - recyclerview : ListView 상위버전으로 결과를 보여주기위해 추가

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'

// constraintlayout
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

// ktx
implementation 'androidx.core:core-ktx:1.3.2'

// recycle view
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.recyclerview:recyclerview-selection:1.1.0-rc03"

// room
implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
implementation "androidx.room:room-ktx:2.2.5"
testImplementation "androidx.room:room-testing:2.2.5"
}


♣ Entity

사용할 데이터 필드를 아래와 같이 정의해줍니다.

 - id : 고유 아이디 필드 (자동으로 생성하도록 설정)

 - title : 할일을 나타내주는 필드

 - highPriority : 할일 중요도를 나타내주는 필드

@Entity
data class Todo(
val title: String,
val highPriority: Boolean
) {
@PrimaryKey(autoGenerate = true)
var id: Int = 0
}



♣ Dao

DataBase 접근할 수 있는 메서드를 정의해줍니다.

@Dao
interface TodoDao {
@Query("SELECT * FROM todo")
fun getAll(): List<Todo>

@Query("SELECT * FROM todo WHERE title LIKE :title")
fun findByTitle(title: String): Todo

@Insert
fun insert(todo: Todo)

@Delete
fun delete(todo: Todo)

@Query("DELETE FROM todo")
fun deleteAll()

@Update
fun update(vararg todo: Todo)

@Query("UPDATE todo SET title = :title, isHighPriority = :isHighPriority WHERE id = :id")
fun update(id: Int, title: String, isHighPriority: Boolean): Int
}


♣ Database

Database 는 아래와같이 싱글톤으로 구현하였습니다.

@Database(entities = [Todo::class], version = 1)
abstract class TodoDataBase : RoomDatabase() {
abstract fun todoDao(): TodoDao?

companion object {
private val sLock = Any()
private var instance: TodoDataBase? = null

fun getInstance(context: Context): TodoDataBase? {
synchronized(sLock) {
if (instance == null) {
instance = Room.databaseBuilder(context,
TodoDataBase::class.java, "todo-db")
.allowMainThreadQueries() // FIXME : 일반적으로 mainThread 에서 사용하지 않음
.build()
}
return instance
}
}
}
}


♣ MainActivity

Room DataBase 를 생성해주고 Dao 메서드를 통해서 사용하는 것을 확인 할 수 있습니다.

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// Room DataBase Load
val todoDataBase = TodoDataBase.getInstance(applicationContext)

// UI Initialize
val etTodo = findViewById<EditText>(R.id.etTodo)
val btnAdd = findViewById<Button>(R.id.btnAdd)
val rvResult = findViewById<RecyclerView>(R.id.rvResult)
val btnDeleteAll = findViewById<Button>(R.id.btnDeleteAll)
val btnDelete = findViewById<Button>(R.id.btnDelete)

val viewManager = LinearLayoutManager(this)
val todoList = todoDataBase?.todoDao()?.getAll()!!
val todoAdapter = TodoAdapter(ArrayList(todoList), todoDataBase)
rvResult.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = todoAdapter
}

// UI Listener
btnAdd.setOnClickListener {
if (etTodo.text.toString().isNotEmpty()) {
val todo = Todo(etTodo.text.toString(), false)
todoDataBase.todoDao()?.insert(todo)
etTodo.setText("")

todoAdapter.addItem(todo)
}
}

btnDeleteAll.setOnClickListener {
todoDataBase.todoDao()?.deleteAll()

todoAdapter.deleteAllItem()
}

btnDelete.setOnClickListener {
val todo = todoAdapter.getSelectedItem()
todo?.run {
todoDataBase.todoDao()?.delete(this)

todoAdapter.deleteItem(this)
}
}
}
}



4. 결과





5. 예제 다운로드



참고자료

Android Developer

모던 안드로이드 Jecpack 활용 (인프런강의)





0 comments: