Definiowanie danych za pomocą elementów dotyczących sal

Jeśli do przechowywania danych aplikacji używasz biblioteki trwałości sal, definiujesz encje reprezentujące obiekty, które chcesz przechowywać. Każdy element odpowiada tabeli w powiązanej bazie danych sal, a każde wystąpienie elementu odpowiada wierszowi danych w odpowiedniej tabeli.

Oznacza to, że możesz używać encji Room do definiowania schematu bazy danych bez konieczności pisania kodu SQL.

Anatomia jednostki

Każdą encję Room definiujesz jako klasę z adnotacją @Entity. Element „Sala” obejmuje pola poszczególnych kolumn w odpowiedniej tabeli w bazie danych, w tym co najmniej 1 kolumnę, która tworzy klucz podstawowy.

Poniższy kod to przykład prostej encji, która definiuje tabelę User z kolumnami ID, imienia i nazwiska:

Kotlin

@Entity
data class User(
    @PrimaryKey val id: Int,

    val firstName: String?,
    val lastName: String?
)

Java

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

    public String firstName;
    public String lastName;
}

Domyślnie sala używa nazwy klasy jako nazwy tabeli bazy danych. Jeśli chcesz, aby tabela miała inną nazwę, ustaw w adnotacji @Entity właściwość tableName. Usługa Room domyślnie używa nazw pól jako nazw kolumn w bazie danych. Jeśli chcesz, aby kolumna miała inną nazwę, dodaj do tego pola adnotację @ColumnInfo i ustaw właściwość name. W poniższym przykładzie pokazano niestandardowe nazwy tabeli i jej kolumn:

Kotlin

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

Java

@Entity(tableName = "users")
public class User {
    @PrimaryKey
    public int id;

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

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

Zdefiniuj klucz podstawowy

Każda encja dotycząca sali musi zdefiniować klucz podstawowy, który jednoznacznie identyfikuje każdy wiersz w odpowiedniej tabeli bazy danych. Najprostszym sposobem na wykonanie tej czynności jest dodanie do pojedynczej kolumny adnotacji @PrimaryKey:

Kotlin

@PrimaryKey val id: Int

Java

@PrimaryKey
public int id;

Zdefiniuj złożony klucz podstawowy

Jeśli chcesz, aby wystąpienia encji były jednoznacznie identyfikowane przez kombinację wielu kolumn, możesz zdefiniować złożony klucz podstawowy, wymieniając te kolumny we właściwości primaryKeys @Entity:

Kotlin

@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
    val firstName: String?,
    val lastName: String?
)

Java

@Entity(primaryKeys = {"firstName", "lastName"})
public class User {
    public String firstName;
    public String lastName;
}

Ignoruj pola

Domyślnie sala tworzy kolumnę dla każdego pola zdefiniowanego w elemencie. Jeśli element zawiera pola, których nie chcesz utrzymywać, możesz dodać do nich adnotacje za pomocą narzędzia @Ignore, tak jak w tym fragmencie kodu:

Kotlin

@Entity
data class User(
    @PrimaryKey val id: Int,
    val firstName: String?,
    val lastName: String?,
    @Ignore val picture: Bitmap?
)

Java

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

    public String firstName;
    public String lastName;

    @Ignore
    Bitmap picture;
}

Jeśli jednostka dziedziczy pola od jednostki nadrzędnej, zazwyczaj łatwiej jest użyć właściwości ignoredColumns atrybutu @Entity:

Kotlin

open class User {
    var picture: Bitmap? = null
}

@Entity(ignoredColumns = ["picture"])
data class RemoteUser(
    @PrimaryKey val id: Int,
    val hasVpn: Boolean
) : User()

Java

@Entity(ignoredColumns = "picture")
public class RemoteUser extends User {
    @PrimaryKey
    public int id;

    public boolean hasVpn;
}

Pokoje obsługują kilka typów adnotacji, które ułatwiają wyszukiwanie szczegółów w tabelach bazy danych. Używaj wyszukiwania pełnotekstowego, chyba że minSdkVersion Twojej aplikacji ma wartość mniejszą niż 16.

Obsługuj wyszukiwanie pełnotekstowe

Jeśli Twoja aplikacja wymaga bardzo szybkiego dostępu do informacji z bazy danych poprzez wyszukiwanie pełnotekstowe, zadbaj o to, aby Twoje encje były oparte na tabeli wirtualnej, która korzysta z modułu rozszerzenia SQLite FTS3 lub FTS4. Aby skorzystać z tej funkcji dostępnej w pokoju w wersji 2.1.0 i nowszych, dodaj do danego elementu adnotację @Fts3 lub @Fts4 w sposób podany w tym fragmencie kodu:

Kotlin

// Use `@Fts3` only if your app has strict disk space requirements or if you
// require compatibility with an older SQLite version.
@Fts4
@Entity(tableName = "users")
data class User(
    /* Specifying a primary key for an FTS-table-backed entity is optional, but
       if you include one, it must use this type and column name. */
    @PrimaryKey @ColumnInfo(name = "rowid") val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String?
)

Java

// Use `@Fts3` only if your app has strict disk space requirements or if you
// require compatibility with an older SQLite version.
@Fts4
@Entity(tableName = "users")
public class User {
    // Specifying a primary key for an FTS-table-backed entity is optional, but
    // if you include one, it must use this type and column name.
    @PrimaryKey
    @ColumnInfo(name = "rowid")
    public int id;

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

Jeśli tabela obsługuje treści w wielu językach, użyj opcji languageId, aby wskazać kolumnę z informacjami o języku w przypadku każdego wiersza:

Kotlin

@Fts4(languageId = "lid")
@Entity(tableName = "users")
data class User(
    // ...
    @ColumnInfo(name = "lid") val languageId: Int
)

Java

@Fts4(languageId = "lid")
@Entity(tableName = "users")
public class User {
    // ...

    @ColumnInfo(name = "lid")
    int languageId;
}

Pokój daje dostęp do kilku innych opcji definiowania encji obsługiwanych przez FTS, w tym do porządkowania wyników, typów tokenizowania i tabel zarządzanych jako zawartość zewnętrzna. Więcej informacji o tych opcjach znajdziesz w dokumentacji FtsOptions.

Kolumny związane z indeksem

Jeśli Twoja aplikacja musi obsługiwać wersje pakietu SDK, które nie obsługują encji opartych na tabelach FTS3 ani FTS4, nadal możesz indeksować niektóre kolumny w bazie danych, aby przyspieszyć wykonywanie zapytań. Aby dodać indeksy do encji, umieść w adnotacji @Entity właściwość indices z listą nazw kolumn, które chcesz uwzględnić w indeksie lub indeksie wieloskładnikowym. Ten fragment kodu ilustruje proces tworzenia adnotacji:

Kotlin

@Entity(indices = [Index(value = ["last_name", "address"])])
data class User(
    @PrimaryKey val id: Int,
    val firstName: String?,
    val address: String?,
    @ColumnInfo(name = "last_name") val lastName: String?,
    @Ignore val picture: Bitmap?
)

Java

@Entity(indices = {@Index("name"),
        @Index(value = {"last_name", "address"})})
public class User {
    @PrimaryKey
    public int id;

    public String firstName;
    public String address;

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

    @Ignore
    Bitmap picture;
}

Czasami pewne pola lub grupy pól w bazie danych muszą być unikalne. Możesz wyegzekwować tę właściwość niepowtarzalności, ustawiając właściwość unique w adnotacji @Index na true. Dzięki podanemu poniżej przykładowi kodu tabela nie może zawierać 2 wierszy zawierających ten sam zestaw wartości w kolumnach firstName i lastName:

Kotlin

@Entity(indices = [Index(value = ["first_name", "last_name"],
        unique = true)])
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?,
    @Ignore var picture: Bitmap?
)

Java

@Entity(indices = {@Index(value = {"first_name", "last_name"},
        unique = true)})
public class User {
    @PrimaryKey
    public int id;

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

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

    @Ignore
    Bitmap picture;
}

Uwzględnij obiekty oparte na wartości automatycznej

W Pokoju 2.1.0 i nowszych możesz używać opartych na Javie niezmiennych klas wartości, do których dodajesz adnotacje przy użyciu @AutoValue, jako encji w bazie danych aplikacji. Ta obsługa jest szczególnie przydatna, gdy 2 wystąpienia encji są uznawane za równe, jeśli ich kolumny zawierają identyczne wartości.

Gdy używasz klas z adnotacjami @AutoValue jako encji, możesz dodawać adnotacje do metod abstrakcyjnych klasy za pomocą elementów @PrimaryKey, @ColumnInfo, @Embedded i @Relation. Jeśli jednak używasz tych adnotacji, musisz za każdym razem dodać adnotację @CopyAnnotations, aby sala mogła prawidłowo zinterpretować automatycznie wygenerowane implementacje metod.

Poniższy fragment kodu zawiera przykład klasy z adnotacją @AutoValue, którą Room rozpoznaje jako encję:

User.java,

@AutoValue
@Entity
public abstract class User {
    // Supported annotations must include `@CopyAnnotations`.
    @CopyAnnotations
    @PrimaryKey
    public abstract long getId();

    public abstract String getFirstName();
    public abstract String getLastName();

    // Room uses this factory method to create User objects.
    public static User create(long id, String firstName, String lastName) {
        return new AutoValue_User(id, firstName, lastName);
    }
}