Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Cómo definir datos con entidades Room

Cuando usas la biblioteca de persistencias Room, defines conjuntos de campos relacionados como entidades. Para cada entidad, se crea una tabla dentro del objeto Database asociado con el fin de retener los elementos. Debes hacer referencia a la clase de entidad a través del arreglo entities de la clase Database.

En el siguiente fragmento de código, se muestra cómo definir una entidad:

Kotlin

    @Entity
    data class User(
        @PrimaryKey var id: Int,
        var firstName: String?,
        var lastName: String?
    )
    

Java

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

        public String firstName;
        public String lastName;
    }
    

Para conservar un campo, Room debe tener acceso a él. Puedes hacer que un campo sea público o puedes proporcionarle un captador y un colocador. Si usas los métodos get y set, ten en cuenta que están basados en las convenciones de JavaBeans de Room.

Cómo usar una clave primaria

Cada entidad debe definir al menos 1 campo como clave primaria. Incluso cuando solo hay 1 campo, aún debes usar la anotación @PrimaryKey en él. Además, si quieres que Room asigne ID automáticos a entidades, puedes configurar la propiedad autoGenerate de @PrimaryKey. Si la entidad tiene una clave primaria compuesta, puedes usar la propiedad primaryKeys de la anotación @Entity, como se muestra en el siguiente fragmento de código:

Kotlin

    @Entity(primaryKeys = arrayOf("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;
    }
    

De forma predeterminada, Room usa el nombre de la clase como el nombre de la tabla de la base de datos. Si quieres que la tabla tenga un nombre diferente, configura la propiedad tableName de la anotación @Entity, como se muestra en el siguiente fragmento de código:

Kotlin

    @Entity(tableName = "users")
    data class User (
        // ...
    )
    

Java

    @Entity(tableName = "users")
    public class User {
        // ...
    }
    

Precaución: En SQLite, los nombres de tabla no distinguen entre mayúsculas y minúsculas.

Al igual que la propiedad tableName, Room usa los nombres de campo como nombres de columna en la base de datos. Si quieres que una columna tenga un nombre diferente, agrega la anotación @ColumnInfo a un campo, como se muestra en el siguiente fragmento de código:

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

Cómo ignorar campos

De forma predeterminada, Room crea una columna para cada campo que se define en la entidad. Si una entidad tiene campos no deseados, puedes usar la anotación @Ignore en ellos, como se muestra en el siguiente fragmento de código:

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

Cuando una entidad hereda campos de una entidad principal, suele ser más fácil usar la propiedad ignoredColumns del atributo @Entity:

Kotlin

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

    @Entity(ignoredColumns = arrayOf("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;
    }
    

Room admite varios tipos de anotaciones que facilitan la búsqueda de detalles en las tablas de la base de datos. Usa la búsqueda en el texto completo, a menos que la minSdkVersion de tu app sea inferior a 16.

Cómo admitir la búsqueda en el texto completo

Si la app requiere un acceso muy rápido a la información de la base de datos mediante la búsqueda en el texto completo (FTS), respalda tus entidades con una tabla virtual que use el módulo de extensión SQLite FTS3 o FTS4. Para usar esta función, disponible en Room 2.1.0 y versiones posteriores, agrega la anotación @Fts3 o @Fts4 a una entidad dada, como se muestra en el siguiente fragmento de código:

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

Cuando una tabla admita contenido en varios idiomas, usa la opción languageId para especificar la columna que almacena la información de idioma de cada fila:

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

Room ofrece varias opciones para definir entidades respaldadas por FTS, como el orden de los resultados, los tipos de tokenizadores y las tablas administradas como contenido externo. Para obtener más información sobre estas opciones, consulta la referencia de FtsOptions.

Columnas específicas del índice

Si la app debe admitir versiones de SDK que no permiten usar entidades respaldadas por tablas FTS3 o FTS4, igual puedes indexar algunas columnas de la base de datos para agilizar las consultas. Para agregar índices a una entidad, incluye la propiedad indices dentro de la anotación @Entity y enumera los nombres de las columnas que quieras incluir en el índice o en el índice compuesto. En el siguiente fragmento de código, se muestra este proceso de anotación:

Kotlin

    @Entity(indices = arrayOf(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;
    }
    

En ocasiones, algunos campos o grupos de campos de una base de datos deben ser únicos. Puedes aplicar esta propiedad de exclusividad con la propiedad unique de una anotación @Index como true. En el siguiente ejemplo de código, se evita que una tabla tenga dos filas con el mismo conjunto de valores para las columnas firstName y lastName:

Kotlin

    @Entity(indices = arrayOf(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;
    }
    

Cómo incluir objetos basados en AutoValue

En Room 2.1.0 y versiones posteriores, puedes usar clases de valores inmutables basadas en Java, que puedes anotar con @AutoValue, como entidades en la base de datos de la app. La compatibilidad es particularmente útil cuando dos instancias de una entidad se consideran iguales si sus columnas tienen valores idénticos.

Cuando usas clases anotadas con @AutoValue como entidades, puedes anotar los métodos abstractos de la clase con @PrimaryKey, @ColumnInfo, @Embedded y @Relation. Sin embargo, si las usas, debes incluir la anotación @CopyAnnotations cada vez, para que Room pueda interpretar correctamente las implementaciones autogeneradas de los métodos.

En el siguiente fragmento de código, se muestra un ejemplo de una clase anotada con @AutoValue que Room reconoce como una entidad:

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