Написание асинхронных запросов DAO

Чтобы запросы не блокировали пользовательский интерфейс, Room не разрешает доступ к базе данных в основном потоке. Это ограничение означает, что вы должны сделать запросы DAO асинхронными. Библиотека Room включает интеграцию с несколькими различными платформами для обеспечения асинхронного выполнения запросов.

Запросы DAO делятся на три категории:

  • Одноразовые запросы на запись , которые вставляют, обновляют или удаляют данные в базе данных.
  • Запросы на однократное чтение , которые считывают данные из вашей базы данных только один раз и возвращают результат со снимком базы данных в этот момент.
  • Наблюдаемые запросы чтения , которые считывают данные из вашей базы данных каждый раз, когда изменяются базовые таблицы базы данных, и выдают новые значения, отражающие эти изменения.

Параметры языка и платформы

Room обеспечивает поддержку интеграции для взаимодействия с конкретными языковыми функциями и библиотеками. В следующей таблице показаны применимые типы возвращаемых данных в зависимости от типа запроса и платформы:

Тип запроса Особенности языка Котлин RxJava Гуава Жизненный цикл реактивного ранца
Однократная запись Сопрограммы ( suspend ) Single , Maybe , Completable ListenableFuture Н/Д
Одноразовое чтение Сопрограммы ( suspend ) Single , Maybe ListenableFuture Н/Д
Наблюдаемое чтение Flow Flowable , Publisher , Observable Н/Д LiveData

В этом руководстве демонстрируются три возможных способа использования этих интеграций для реализации асинхронных запросов в ваших DAO.

Котлин с Flow и курутинами

Kotlin предоставляет возможности языка, которые позволяют писать асинхронные запросы без сторонних фреймворков:

  • В комнате 2.2 и выше вы можете использовать функциональность Kotlin Flow для написания наблюдаемых запросов.
  • В версии 2.1 и выше вы можете использовать ключевое слово suspend , чтобы сделать запросы DAO асинхронными с использованием сопрограмм Kotlin .

Java с RxJava

Если ваше приложение использует язык программирования Java, вы можете использовать специализированные возвращаемые типы из платформы RxJava для написания асинхронных методов DAO. Room обеспечивает поддержку следующих типов возврата RxJava 2:

  • Для однократных запросов Room 2.1 и выше поддерживают типы возвращаемых данных Completable , Single и Maybe .
  • Для наблюдаемых запросов Room поддерживает типы возвращаемых значений Publisher , Flowable и Observable .

Кроме того, Room 2.3 и выше поддерживают RxJava 3.

Java с LiveData и Guava

Если ваше приложение использует язык программирования Java и вы не хотите использовать платформу RxJava, вы можете использовать следующие альтернативы для написания асинхронных запросов:

  • Вы можете использовать класс-оболочку LiveData из Jetpack для написания асинхронных наблюдаемых запросов.
  • Вы можете использовать оболочку ListenableFuture из Guava для написания асинхронных одноразовых запросов.

Написание асинхронных одноразовых запросов

Одноразовые запросы — это операции с базой данных, которые выполняются только один раз и во время выполнения получают снимок данных. Вот несколько примеров асинхронных одноразовых запросов:

Котлин

@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): List
}

Ява

@Dao
public interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public Completable insertUsers(List users);

    @Update
    public Completable updateUsers(List users);

    @Delete
    public Completable deleteUsers(List users);

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

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

Ява

@Dao
public interface UserDao {
    // Returns the number of users inserted.
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public ListenableFuture insertUsers(List users);

    // Returns the number of users updated.
    @Update
    public ListenableFuture updateUsers(List users);

    // Returns the number of users deleted.
    @Delete
    public ListenableFuture deleteUsers(List users);

    @Query("SELECT * FROM user WHERE id = :id")
    public ListenableFuture loadUserById(int id);

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

Пишите наблюдаемые запросы

Наблюдаемые запросы — это операции чтения, которые выдают новые значения всякий раз, когда происходят изменения в любой из таблиц, на которые ссылается запрос. Один из способов использования этого — поддерживать актуальность отображаемого списка элементов по мере того, как элементы в базовой базе данных вставляются, обновляются или удаляются. Вот несколько примеров наблюдаемых запросов:

Котлин

@Dao
interface UserDao {
    @Query("SELECT * FROM user WHERE id = :id")
    fun loadUserById(id: Int): Flow

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

Ява

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

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

Ява

@Dao
public interface UserDao {
    @Query("SELECT * FROM user WHERE id = :id")
    public LiveData loadUserById(int id);

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

Дополнительные ресурсы

Дополнительные сведения об асинхронных запросах DAO см. в следующих дополнительных ресурсах:

Образцы

Блоги