Search code examples
androidkotlinandroid-roomrx-java2android-livedata

What approach should I use in the DAO to manipulate data in a database using Room?


For now I use this code in my DAO:

@Dao
interface NotesDao {

    @Query("SELECT * FROM Notes")
    fun getAllNotes(): List<Notes?>?

    @Query("SELECT * FROM Notes WHERE not hidden AND not grouped")
    fun getNotes(): List<Notes?>?

    @Query("SELECT * FROM Notes WHERE id = :id")
    fun getById(id: Long): Notes?

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(notes: Notes?)

    @Update
    fun update(notes: Notes?)

    @Delete
    fun delete(notes: Notes?)
}

But in many tutorials I either see Flowable<List<Notes>> instead of List<Notes> or LiveData<List<Notes>>. Which approach is preferable?


Solution

  • There are two factors you should consider:

    1. All interactions with database (both queries and updates) should be outside main thread.
    2. In some use-cases you want single "one-shot" query, in other - you want your query to be "live" - i.e. to return updated result whenever data was changed (Observer pattern).

    Using Kotlin you have two main options (what's better is a matter of taste. In some tutorials you can see also AsyncTask or Thread executors for switching off the main thread):

    1. Use RxJava (use Flowable for "live" queries, Single - for "one-shot" queries and one of the Single/Completable/Maybe for insert/update/delete). Using RxJava you can use built-in mechanism for switching off the main thread.
    2. Use Coroutines (and keyword suspend) for insert/update/delete, and LiveData or Flow (from coroutines library) for "live" queries, or suspend - for "one-shot" queries. suspend lets to switch from the main thread. If you use LiveData/Flow you don't need suspend, since Room does it itself.

    See also official documentation for additional hints.