👍 SELECT문에 RxJava 적용하기

  • Dao
@Dao
interface UserDao : BaseDao<User> {

    @Query("SELECT * FROM user_table WHERE id=:id")
    fun getUser(id: String?): Single<User>
}
  • Repository
class RoomRepository(application: Application) {

    private var userDao: UserDao

    init {
        val database = RoomDatabase.getInstance(application)!!
        userDao = database.userDao()
    }

    fun getUser(id: String): Single<User> {
        return userDao.getUser(id)
    }
}
  • ViewModel
class ProfileViewModel(application: Application) : BaseViewModel<Profile>(application) {

    var id: MutableLiveData<String> = MutableLiveData()

    fun getUser() {           
        CompositeDisposable().add(repository.getUser(id)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(object : DisposableSingleObserver<User>() {
                override fun onSuccess(user: User) {
                  id.value = user
              }

              override fun onError(e: Throwable) {
                  // error event
              }
        })
    }
}
  • View
class ProfileActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel.getUser("aaa")

        viewModel.id.observe(this, Observer {
             // 이벤트
        })

    }
}

Flowable / Maybe / Single 셋 중 하나를 사용할 수 있는데
나는 값을 받아왔는지 못받아 왔는지만 확인하면 된다 판단하여 Single을 사용하였다.
해당 행이 없으면 onError를 실행시키고 안전하게 값을 받아오면 onSuccess를 실행시킨다.

✌ Insert / Update / Delete 에 RxJava 적용하기

  • Dao
@Dao
interface BaseDao<ET> {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(entity: ET): Completable

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(entity: Array<out ET>): Completable

    @Update
    fun update(entity: ET): Completable

    @Delete
    fun delete(entity: ET): Completable

}
  • Repository
class RoomRepository(application: Application) {

    private var userDao: UserDao

    init {
        val database = RoomDatabase.getInstance(application)!!
        userDao = database.userDao()
    }

    fun insertUser(entity: User): Completable { return userDao.insert(entity) }
    fun updateUser(entity: User): Completable { return userDao.update(entity) }
    fun deletUser(entity: User): Completable { return userDao.delete(entity) }
}
  • ViewModel
class LoginViewModel(application: Application) : BaseViewModel(application) {

    val successEvent: SingleLiveEvent<Any> = SingleLiveEvent()

    private fun insertUser(user: User) {
        CompositeDisposable().add(repository.insertUser(user)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { successEvent.call() },
                        { error -> // error event 
                        }))
    }
}
  • View
class LoginActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel.insertUser(User("aaa","aaa","2019-08-27","m", "01000000000", "", "hello" , "", 20))

        viewModel.onSuccessEvent.observe(this@LoginActivity, Observer {
             startActivityWithFinish(MainActivity::class.java)
        })
    }
}

Completable을 사용하면 해당 이벤트가 성공적으로 끝났을때
success 이벤트가 실행되고 실패했을때 error 이벤트를 실행 시킨다.
Single<Integer> 혹은 Maybe<Integer> 를 사용할 수도 있지만 이는 이벤트가 성공적으로 끝나고 영향 받은 행수까지 받환하여 주기 때문에 내 프로젝트에는 불필요하다고 생각했다.

👌 마무리

Room을 잘 활용하면 정말 유용할 것 같다. SQLITE 보다 더 간단하고 좋은 기술이라고 생각 한다.
특히 내부 DB에 RxJava을 쉽게 사용할 수 있는 것은 정말 큰 이점이다.