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

Попробуйте Kotlin Multiplatform
Kotlin Multiplatform позволяет использовать уровень базы данных совместно с другими платформами. Узнайте, как настроить и использовать Room Database в KMP.

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

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

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

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

Настраивать

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

Котлин

dependencies {
    val room_version = "2.7.2"

    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")
}

Круто

dependencies {
    def room_version = "2.7.2"

    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();
}

Примечание: Если ваше приложение работает в одном процессе, при создании экземпляра объекта AppDatabase следует использовать шаблон проектирования Singleton. Каждый экземпляр 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, ознакомьтесь со следующими дополнительными ресурсами:

Образцы

Codelabs

Блоги