Android Room Entity使用

说明:

Android Room 第二篇 - Entity使用

主要介绍entity的作用

原文地址:https://developer.android.com/training/data-storage/room/defining-data

第一篇:Android Room概述

使用Room entities 来定义数据

当你在使用Room的时候,定义了一组相关的字段作为一个实体。对于每个实体,都会通过在数据库里面创建一张表的方式来处理这些数据。

通常来说,Room 会为实体类中定义的每个字段在数据库中创建“列”。如果实体类中有某个字段你不想在数据库中进行存储的,你可以对这些字段使用@Ignore注解。

下面这个代码块展示了如何定义一个实体

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

    public String firstName;
    public String lastName;

    @Ignore
    Bitmap picture;
}

为了能够保存某个字段,Room必须能够对它进行操作。你可以使用public修饰符,或者你可以提供getter和setter方法。如果你选择后者,记住Room是基于JavaBeans约定的。

主键

每个实体必须定义至少一个字段作为主键。即使是实体只有一个字段,你仍然需要对该字段使用@PrimaryKey注解。同时,如果你想通过Room来自动分配ID,也可以设置@PrimaryKey的autoGenerate属性。如果实体有组合主键,你可以通过primaryKeys属性来说声明,下面是代码示例:

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

    @Ignore
    Bitmap picture;
}

通常来说,Room会使用类名作为数据库表名。如果你希望自定义表名,在@Entity注解下设置tableName属性,下面是代码示例:

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

注意:在SQLite中,表名是不区分大小写的

和tableName属性类似。Room用变量名称作为数据库表的字段名称。如果你希望字段名和变量名不一样,在变量处加上@ColumnInfo注解,下面是代码示例:

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

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

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

    @Ignore
    Bitmap picture;
}

索引和唯一性

根据你操作数据的方式,可能你需要通过索引来提高查询数据库的速度。想要对实体添加索引,可以通过在@Entity注解下添加indices属性来实现,加上你想要添加索引的列名。下面是代码示例:

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

有时候,一些字段需要具有唯一性。你可以通过在@Index注解下设置unique为true,即可强制实现该字段的唯一性。下面这段代码就防止firstName和lastName这两列具有相同的属性,保证其唯一性

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

定义对象之间的关系

由于SQLite是关系型数据库,你可以指定对象之间的关系。虽然大多数对象关系型数据库都匀速实体对象互相引用,但是Room是明确禁止的。如果你想知道这个决定背后的技术原因,可以参见:Understand why Room doesn’t allow object references.

虽然你不能使用直接关系,Room仍然允许你在实体之间定义外键。

例如,如果有另一个实体叫做Book,你可以在User实体下使用@ForeignKey注解来定义他们之间的关系,就像下面的代码段所示:

@Entity(foreignKeys = @ForeignKey(entity = User.class,
                                  parentColumns = "id",
                                  childColumns = "user_id"))
public class Book {
    @PrimaryKey
    public int bookId;

    public String title;

    @ColumnInfo(name = "user_id")
    public int userId;
}

外键是非常强大的,它能够允许你在引用实体发生改变时,指定当前实体做出相应操作。例如,当一个在@ForeignKey注解使用了onDelete = CASCADE 语句的User被删除了,你可以让SQLite删除这个User下所有的books

注意: SQLite 处理 @Insert(onConflict = REPLACE) 的时候看作是 REMOVE 和 REPLACE 操作,而不是单纯的UPDATE操作。这个方法会替换冲突值,同时也会对外键约束有影响。更多细节请看:SQLite documentation

创建嵌套对象

有时,你希望将实体或普通旧Java对象(POJO)表达为数据库逻辑中的一个整体,即使该对象包含多个字段。在这些情况下,你可以使用@Embedded批注来表示要分解到表中子字段的对象。然后,你可以像查找其他单个列一样查询嵌入字段。

例如,我们的User类可以包含Address类型的字段,它表示名为street,city,state和postCode的字段的组合。要将组合列分别存储在表中,请在User类中包含使用@Embedded注释的Address字段,如以下代码段所示:

public class Address {
    public String street;
    public String state;
    public String city;

    @ColumnInfo(name = "post_code")
    public int postCode;
}

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

    public String firstName;

    @Embedded
    public Address address;
}

这个表示User对象的表包含具有以下名称的列:id,firstName,street,state,city和post_code。

注意:嵌套字段能够包含在其他嵌套内

如果实体具有多个相同类型的嵌入字段,则可以通过设置prefix属性使每个列保持唯一。然后,Room将提供的值添加到嵌入对象中每个列名称的开头。

猜你喜欢

转载自blog.csdn.net/blue_zy/article/details/80964138
今日推荐