안드로이드

[Android] Android DB Room에 대해 알아보자

코딩하는후운 2022. 10. 25. 11:27
반응형

Android DB Room에 대해 알아보자

안드로이드 JetPack
-Foundation
-Architecture
-Behavior
-Ui
4개의 구성

먼저 Architecture는 다시
Databinding, Lifecycles, LiveData, Navigation,Paging, Room, ViewModel, WorkManager
이렇게 8개로 세분화 할수 있습니다.


https://black-jin0427.tistory.com/53?category=727620

1.Room
ORM?
Room을 알아보기 전에 ORM에 대한 개념을 살펴보겠습니다.
ORM이란 Object Relational Mapping 으로 데이터베이스와 객체 지향 프로그래밍 언어간의 호환되지 않는
데이터를 변환하는 프로그래밍 기법으로 DB테이블과 매칭되는 객체를 만들고 그 객체에서 DB를 관리하는 것입니다.

Room?
안드로이드 아키텍처 컴포넌트 룸 라이브러리는 안드로이드 앱에서 SQLite데이터베이스를 쉽고 편리하게 사용할 수
있도록 하는 기능입니다.
이를 다시 정리하면 SQLite위에 만든 구글의 새로운 ORM이라고 할 수 있습니다. 룸 라이브러리는 엔티티,
데이터 접근 객체, 룸 데이터베이스, 총 세개의 구성요소로 나뉩니다.

그럼 룸 라이브러리를 어떻게 사용하는지 순서대로 설명하겠습니다.

1. build.gradle파일의 dependencies에 추가해 줍니다.
//room

implementation "android.arch.persistence.room:runtime:$roomVersion"
kapt "andoid.arch.persistence.room:compiler:$roomVersion"



2. 엔티티(Entity)를 만들어 줍니다.
엔티티는 데이터베이스에 저장할 데이터의 형식을 정의합니다.

저는 person데이터를 만들어서 이름과 직업 변수를 갖는 객체를 만들었습니다.

@Entity
class Person(
    @PrimaryKey val id: Int,
    val name: String,
    val job: String)


적어도 한개의 PrimaryKey가 만드시 있어야 합니다.


3.데이터 접근 객체(Data Access Object)를 생성합니다.
데이터 접근 객체는 데이터베이스를 통해 수행할 작업을 정의한 클래스 입니다.
데이터의 삽입, 수정, 삭제 작업이나 저장된 데이터를 불러오는 작업 등을 함수 형태로 정의합니다.

@Dao
interface PersonDao{
  @Query("SELECT * FROM person")
  fun getAllPerson(): List<Person>

  @Query("DELETE FROM person")
  fun clearAll()

  @Insert
  fun insert(vararg person: Person)

  @Update
  fun update(vararg person: Person)

  @Delete
  fun delete(vararg person: Person)
}


데이터를 추가 할 때 같은 primary key값을 가진 객체를 추가하면 에러가 발생합니다.
이미 저장된 항목이 있을 경우 데이터를 덮어 씌우는 방법이 있습니다.
//이미 저장된 항목이 있을 경우 데이터를 덮어씁니다.
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(vararg person: Person)

위와 같이 onConflict를 추가해 주면 동일 항목의 경우 자동으로 데이터를 덮어 씌웁니다.


4. 룸 데이터베이스(Room Database)를 생성합니다.
룸 데이터베이스에서 데이터베이스를 생성하거나 버전을 관리를 합니다.

@Database(entities = arrayOf(Person::class), version = 1)
abstract class PersonDatabase: RoomDatabase(){
  abstract fun getPersonDao(): PersonDao

  companion object{
    private var INSTANCE: PersonDatabase? = null

    fun getInstance(context: Context): PersonDatabase?{
      if(INSTANCE == null){
        synchronized(PersonDatabase::class){
          INSTANCE = Room.databaseBuilder(
            context,
            PersonDatabase::class.java,
            "person.db")
            .build()
          )
        }
      }

      return INSTANCE
    }
  }
}




5. 데이터 삽입과 불러오기
데이터 삽입과 불러오기 등 데이터를 처리하는 작업은 모두 Background Thread에서 처리해야 합니다.
데이터 삽입

val person = Person(0, "blackJin", "Developer")

PersonDatabase
      .getInstance(context)!!
      .getPersonDao()
      .insert(person)

데이터 불러오기
val items = PersonDatabase
                .getInstance(context)!!
                .getPersonDao()
                .getAllPerson()



Using RxJava in Room
Room의 데이터는 모두 백그라운드 쓰레드에서 처리해야 합니다.
백그라운드 쓰레드에서 사용할 수 있는 강력한 도구가 바로 RxJava입니다.

1.build.grade파일의 dependencies에 추가해 줍니다.
Room 라이브러리에 Rx를 적용할 수 있게 해줍니다.

implementation "android.arch.persistence.room:rxjava2:$roomVersion"


Android Studio 에서 Rx 를 사용할 수 있게 해줍니다.

현재 기준 rxAndroidVersion = '2.0.2' , rxJavaVersion = '2.1.3'

implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion"



2.PersonDao 에서 데이터를 받는 getAllPerson의 반환값을 Flowable로 변경합니다.

@Dao
interface PersonDao{
  ...

  @Query("SELECT * FROM person")
  fun getAllPersonRx(): Flowable<List<Person>>

  ...
}



Flowable 형태의 자료를 반환하면 데이터베이스가 변경되면 알림을 받아 새로운 자료를 가져옵니다.
따라서 항상 최신 데이터를 유지하게 됩니다.
재밌는 부분은 room에서의 Flowable은 complete를 수행하지 않는다는 것입니다.


3.데이터를 받고 처리할 화면에서 아래 코드를 사용하시면 됩니다.
데이터 삽입

val person = Person(0, "blackJin", "Developer")

Observable.just(person)
      .subscribeOn(Schedulers.io())
      .subscribe({
        PersonDatabase
            .getInstance(context)!!
            .getPersonDao()
            .insert(person)
      },{
        Log.e("TAG", it.message)
      })



Observable를 사용하여 백그라운드 쓰레드에서 데이터를 처리합니다.

자동으로 PrimaryKey를 증가시켜주기.

@Entity
class Person(
  @PrimaryKey(autoGenerate = true)
  val id: Int,
  val name: String,
  val job: String)


데이터 불러오기
PersonDatabase
    .getInstance(context)!!
    .getPersonDao()
    .getAllPersonRx()
    .observeOn(AndroidSchedulers.mainThread())
    .doOnSubscribe{
      //구독시 사용할 함수
    }
    .doOnTerminate{
      //구독이 끝날 때 사용할 함수
    }
    .subscribe({
      adapter.setItem(it.toMutableList())
    },{
      Log.e("tag", it.message)
    })

 

 

 

참조 :

https://black-jin0427.tistory.com/50?category=727620 

 

[Android, jetpack] Android Jetpack

안녕하세요. 블랙진입니다. 이번에 Google 2018 i/o 에서 더 빠른 Android 앱 개발을 위한 차세대 컴포넌트, 도구 및 아키텍처 지침인 Android Jetpack 을 소개했습니다. 먼저 안드로이드 제트팩에 관한 개

black-jin0427.tistory.com

 

반응형