Сохраните данные в локальной базе данных с помощью Room Part Android Jetpack .

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

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

  • Проверка SQL-запросов во время компиляции.
  • Удобные аннотации, которые минимизируют повторяющийся и подверженный ошибкам шаблонный код.
  • Оптимизированные пути миграции базы данных.

По этим соображениям мы настоятельно рекомендуем вам использовать Room вместо прямого использования API SQLite .

Настраивать

Чтобы использовать Room в своем приложении, добавьте следующие зависимости в файл build.gradle вашего приложения.

Kotlin

dependencies {
    val room_version = "2.6.1"

    implementation("androidx.room:room-runtime:$room_version")

    // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
    // See Add the KSP plugin to your project
    ksp("androidx.room:room-compiler:$room_version")

    // If this project only uses Java source, use the Java annotationProcessor
    // No additional plugins are necessary
    annotationProcessor("androidx.room:room-compiler:$room_version")

    // optional - Kotlin Extensions and Coroutines support for Room
    implementation("androidx.room:room-ktx:$room_version")

    // optional - RxJava2 support for Room
    implementation("androidx.room:room-rxjava2:$room_version")

    // optional - RxJava3 support for Room
    implementation("androidx.room:room-rxjava3:$room_version")

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation("androidx.room:room-guava:$room_version")

    // optional - Test helpers
    testImplementation("androidx.room:room-testing:$room_version")

    // optional - Paging 3 Integration
    implementation("androidx.room:room-paging:$room_version")
}

Groovy

dependencies {
    def room_version = "2.6.1"

    implementation "androidx.room:room-runtime:$room_version"

    // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
    // See KSP Quickstart to add KSP to your build
    ksp "androidx.room:room-compiler:$room_version"

    // If this project only uses Java source, use the Java annotationProcessor
    // No additional plugins are necessary
    annotationProcessor "androidx.room:room-compiler:$room_version"

    // optional - RxJava2 support for Room
    implementation "androidx.room:room-rxjava2:$room_version"

    // optional - RxJava3 support for Room
    implementation "androidx.room:room-rxjava3:$room_version"

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation "androidx.room:room-guava:$room_version"

    // optional - Test helpers
    testImplementation "androidx.room:room-testing:$room_version"

    // optional - Paging 3 Integration
    implementation "androidx.room:room-paging:$room_version"
}

Основные компоненты

В Room есть три основных компонента:

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

Класс базы данных предоставляет вашему приложению экземпляры DAO, связанные с этой базой данных. В свою очередь, приложение может использовать DAO для извлечения данных из базы данных в виде экземпляров связанных объектов объектов данных. Приложение также может использовать определенные объекты данных для обновления строк из соответствующих таблиц или для создания новых строк для вставки. Рисунок 1 иллюстрирует взаимосвязь между различными компонентами Room.

Рисунок 1. Схема архитектуры библиотеки Room.

Пример реализации

В этом разделе представлен пример реализации базы данных Room с одним объектом данных и одним DAO.

Сущность данных

Следующий код определяет объект данных User . Каждый экземпляр User представляет строку в таблице user в базе данных приложения.

Котлин

@Entity
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)

Ява

@Entity
public class User {
    @PrimaryKey
    public int uid;

    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;
}

Дополнительные сведения об объектах данных в Room см. в разделе Определение данных с помощью объектов Room .

Объект доступа к данным (DAO)

Следующий код определяет DAO под названием UserDao . UserDao предоставляет методы, которые остальная часть приложения использует для взаимодействия с данными в user таблице.

Котлин

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<User>

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    fun loadAllByIds(userIds: IntArray): List<User>

    @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
           "last_name LIKE :last LIMIT 1")
    fun findByName(first: String, last: String): User

    @Insert
    fun insertAll(vararg users: User)

    @Delete
    fun delete(user: User)
}

Ява

@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List<User> getAll();

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    List<User> loadAllByIds(int[] userIds);

    @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
           "last_name LIKE :last LIMIT 1")
    User findByName(String first, String last);

    @Insert
    void insertAll(User... users);

    @Delete
    void delete(User user);
}

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

База данных

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

  • Класс должен быть помечен аннотацией @Database , которая включает массив entities , в котором перечислены все объекты данных, связанные с базой данных.
  • Класс должен быть абстрактным классом, расширяющим RoomDatabase .
  • Для каждого класса DAO, связанного с базой данных, класс базы данных должен определить абстрактный метод, который не имеет аргументов и возвращает экземпляр класса DAO.

Котлин

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Ява

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

Примечание. Если ваше приложение выполняется в одном процессе, вам следует следовать шаблону проектирования Singleton при создании экземпляра объекта AppDatabase . Каждый экземпляр RoomDatabase довольно дорог, и вам редко требуется доступ к нескольким экземплярам в рамках одного процесса.

Если ваше приложение работает в нескольких процессах, включите enableMultiInstanceInvalidation() в вызов построителя базы данных. Таким образом, если у вас есть экземпляр AppDatabase в каждом процессе, вы можете сделать недействительным общий файл базы данных в одном процессе, и это признание недействительным автоматически распространяется на экземпляры AppDatabase в других процессах.

Использование

После того как вы определили объект данных, DAO и объект базы данных, вы можете использовать следующий код для создания экземпляра базы данных:

Котлин

val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "database-name"
        ).build()

Ява

AppDatabase db = Room.databaseBuilder(getApplicationContext(),
        AppDatabase.class, "database-name").build();

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

Котлин

val userDao = db.userDao()
val users: List<User> = userDao.getAll()

Ява

UserDao userDao = db.userDao();
List<User> users = userDao.getAll();

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

Чтобы узнать больше о Room, см. следующие дополнительные ресурсы:

Образцы

Кодлабы

Блоги