본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] Write asynchronous DAO queries - Room 에 대해 알아보자

by 돼지왕 왕돼지 2021. 5. 6.
반응형

-

UI 에서 query 하는 것을 막기 위해 room 은 main thread 에서 db 에 접근하는 것을 허락하지 않고 있다.

이 말은 DAO query 를 async 로 해야 한다는 것을 의미한다.

Room lib 은 async query 를 위해 여러개의 framework 를 통합시켰다.

 

 

-

DAO query 는 3개의 category 로 구분될 수 있다.

    insert, update, delete 등의 one-shot write query

    one-shot read query

    observable read query

 

 

 

Language and framework options

 

-

One-shot write

    Coroutines(suspend)

    Single<T>, Maybe<T>, Completable

    ListenableFuture<T>

 

One-shot read

    Coroutines(suspend)

    Single<T>, Maybe<T>

    ListenableFuture<T>

 

Observable read

    Flow<T>

    Flowable<T>, Publisher<T>, Observable<T>

    LiveData

 

 

 

* Kotlin with Flow and coroutines

 

-

Room 2.2 이상에서 Observable query 에 대해 Kotlin Flow 기능을 사용할 수 있다.

Room 2.1 이상에서 DAO query 에 suspend keyword 를 사용할 수 있다.

(Kotlin Flow 와 coroutine 을 room 과 함께 사용하려면 room-ktx dependency 를 정의해주는 것을 잊지 말자.)

 

 

* Java with RxJava

 

-

Room 2.1 에상에서 one-shot query 에 대해 Completable, Single<T>, Maybe<T> 를 return type 으로 지원한다.

Observable query 에 대해 Publisher<T>, Flowable<T>, Observable<T> 를 지원한다.

(RxJava 를 room 과 함께 사용하려면 room-rxjava2 dependency 를 정의해주는 것을 잊지 말자.)

 

 

* Java with LiveData and Guava

 

-

LiveData 와 ListenableFuture<T> 를 사용할 수 있다.

(Guava 를 room 과 함께 사용하려면 room-guava dependency 를 정의해주는 것을 잊지 말자.)

 

 

 

Write asynchronous one-shot queries

 

-

one-shot query 는 db 에 대해 1회 query 를 하고 그 snapshot 을 제공해주는 것을 이야기한다.

// Kotlin coroutine
@Dao
interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUsers(vararg users: User)

    @Update
    suspend fun updateUsers(vararg users: User)

    @Delete
    suspend fun deleteUsers(vararg users: User)

    @Query("SELECT * FROM user WHERE id = :id")
    suspend fun loadUserById(id: Int): User

    @Query("SELECT * from user WHERE region IN (:regions)")
    suspend fun loadUsersByRegion(regions: List<String>): List<User>
}

 

// RxJava
@Dao
public interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public Completable insertUsers(List<User> users);

    @Update
    public Completable updateUsers(List<User> users);

    @Delete
    public Completable deleteUsers(List<User> users);

    @Query("SELECT * FROM user WHERE id = :id")
    public Single<User> loadUserById(int id);

    @Query("SELECT * from user WHERE region IN (:regions)")
    public Single<List<User>> loadUsersByRegion(List<String> regions);
}

 

 

 

Write observable queries

 

-

Observable query 는 table 에 변경이 생겼을 때마다 새로운 값을 전달해주는 read operation 을 이야기한다.

 

 

-

// Kotlin coroutines
@Dao
interface UserDao {
    @Query("SELECT * FROM user WHERE id = :id")
    fun loadUserById(id: Int): Flow<User>

    @Query("SELECT * from user WHERE region IN (:regions)")
    fun loadUsersByRegion(regions: List<String>): Flow<List<User>>
}

 

// RxJava
@Dao
public interface UserDao {
    @Query("SELECT * FROM user WHERE id = :id")
    public Flowable<User> loadUserById(int id);

    @Query("SELECT * from user WHERE region IN (:regions)")
    public Flowable<List<User>> loadUsersByRegion(List<String> regions)
}

 

 

-

참고자료

https://developer.android.com/training/data-storage/room/async-queries

 

 

반응형

댓글