Zapisywanie danych w lokalnej bazie danych za pomocą opcji Sala Zawiera Android Jetpack.

Aplikacje, które obsługują niezwykłe ilości uporządkowanych danych, mogą wiele zyskać dzięki na przechowywaniu tych danych lokalnie. Najczęstszym przypadkiem użycia jest buforowanie odpowiednich wybranych danych, dzięki czemu, gdy urządzenie nie może uzyskać dostępu do sieci, użytkownik może przeglądać je także offline.

Biblioteka trwałości pomieszczeń zapewnia warstwę abstrakcji w standardzie SQLite, aby umożliwić i płynny dostęp do bazy danych przy jednoczesnym wykorzystaniu wszystkich możliwości SQLite. W szczególności Goście pokoju mają:

  • Weryfikacja zapytań SQL w czasie kompilacji.
  • Adnotacje wygodne, które minimalizują ilość powtarzalnych i podatnych na błędy powtarzalnych treści w kodzie.
  • Uproszczone ścieżki migracji bazy danych.

Z tego względu zdecydowanie zalecamy bezpośredniego korzystania z interfejsów API SQLite.

Konfiguracja

Aby używać pokoju w aplikacji, dodaj te zależności do warunku Plik build.gradle:

Odlotowe

dependencies {
    def room_version = "2.6.1"

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

    // To use Kotlin annotation processing tool (kapt)
    kapt "androidx.room:room-compiler:$room_version"
    // To use Kotlin Symbol Processing (KSP)
    ksp "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"
}

Kotlin

dependencies {
    val room_version = "2.6.1"

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

    // To use Kotlin annotation processing tool (kapt)
    kapt("androidx.room:room-compiler:$room_version")
    // To use Kotlin Symbol Processing (KSP)
    ksp("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")
}

Główne komponenty

W pokoju znajdują się 3 główne elementy:

  • Klasa bazy danych, która zawiera i służy jako główny punkt dostępu dla bazowego połączenia z i trwałe dane aplikacji.
  • encje danych, które reprezentują w bazie danych aplikacji.
  • obiekty dostępu do danych, które udostępniać metody, których aplikacja może używać do wysyłania zapytań, aktualizowania, wstawiania i usuwania zapytań dane w bazie danych.

Klasa bazy danych udostępnia aplikacji instancje DAO powiązane z tę bazę danych. Z kolei aplikacja może używać DAO do pobierania danych z jako instancje powiązanych obiektów encji danych. Aplikacja może też używasz zdefiniowanych encji danych do aktualizowania wierszy z odpowiednich tabel, aby utworzyć nowe wiersze do wstawienia. Ilustracja 1 przedstawia zależność między z różnych komponentów pokoju.

Rysunek 1. Schemat architektury biblioteki sal.

Przykładowa implementacja

W tej sekcji przedstawiamy przykładową implementację bazy danych sal z jednym encji danych i pojedynczego DAO.

Encja danych

Poniższy kod definiuje encję danych User. Każde wystąpienie instancji User reprezentuje wiersz w tabeli user w bazie danych aplikacji.

Kotlin

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

Java

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

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

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

Więcej informacji o elementach danych w pokoju znajdziesz w artykule Definiowanie danych za pomocą Pokoju .

Obiekt dostępu do danych (DAO)

Ten kod definiuje identyfikator DAO o nazwie UserDao. UserDao udostępnia metod używanych przez resztę aplikacji do interakcji z danymi w tabeli user.

Kotlin

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

Java

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

Więcej informacji o DAO znajdziesz w artykule Uzyskiwanie dostępu do danych za pomocą Pokoju DAO.

Baza danych

Ten kod definiuje klasę AppDatabase do przechowywania bazy danych. AppDatabase definiuje konfigurację bazy danych i jest główną funkcją aplikacji w aplikacji i punkt dostępu do trwałych danych. Klasa bazy danych musi spełniać następujące warunki:

  • Do zajęć musisz dodać adnotację z @Database adnotacja, w tym entities tablica, która zawiera listę wszystkich encji danych powiązanych z bazą danych.
  • Klasa musi być klasą abstrakcyjną, która rozciąga się RoomDatabase
  • Dla każdej klasy DAO powiązanej z bazą danych klasa bazy danych musi zdefiniować metodę abstrakcyjną, która ma zero argumentów i zwraca instancję na zajęciach DAO.

Kotlin

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

Java

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

Uwaga: jeśli aplikacja działa w ramach jednego procesu, postępuj zgodnie z instrukcjami wzorzec projektowy singleton podczas tworzenia instancji AppDatabase obiektu. Każde wystąpienie typu RoomDatabase jest dość drogie, a rzadko potrzebują dostępu do wielu instancji w ramach pojedynczego procesu.

Jeśli aplikacja działa w wielu procesach, dodaj do niej wartości enableMultiInstanceInvalidation() w kreatorze baz danych . Dzięki temu, gdy masz instancję AppDatabase w każdym procesie możesz unieważnić udostępniony plik bazy danych w jednym procesie, a to unieważnienie zostanie automatycznie rozpowszechnione w instancjach AppDatabase w innych procesach.

Wykorzystanie

Po zdefiniowaniu encji danych, DAO i obiektu bazy danych może użyć tego kodu, aby utworzyć instancję bazy danych:

Kotlin

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

Java

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

Następnie możesz użyć metod abstrakcyjnych z interfejsu AppDatabase, aby pobrać instancję DAO. Dzięki temu możesz używać metod z instancji DAO do interakcji z bazą danych:

Kotlin

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

Java

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

Dodatkowe materiały

Więcej informacji o pokoju znajdziesz w tych dodatkowych materiałach:

Próbki

Ćwiczenia z programowania

Blogi