美文网首页开源库
[译] 通过 Room entities 定义数据 ---Roo

[译] 通过 Room entities 定义数据 ---Roo

作者: 风雪围城 | 来源:发表于2017-12-13 00:36 被阅读0次

    本文翻译自官网
    使用Room进行持久化存储---综述
    通过 Room entities 定义数据 ---Room 系列(1)
    使用 Room 的 DAO 访问数据---Room 系列(2)
    Android 中使用 Room 实践
    当使用 Room 持久化库 的时候,我们需要定义一系列相关的成员作为 entities 。每个 entity 将被映射为一个 Database 中的 table。
    默认情况下,Room 会为 Entity 中的每个成员创建一个 column。如果你不想对其中的某些成员进行持久化,可以使用 @Ingore 注解。
    下面代码块,展示了怎样定义一个 entity:

    @Entity
    class User {
        @PrimaryKey
        public int id;
    
        public String firstName;
        public String lastName;
    
        @Ignore
        Bitmap picture;
    }
    

    持久化成员之后,Room 必须有能力能够访问到它们。这就意味着需要把该成员设置为 public ,或者提供 getter、setter 方法能够访问到。

    使用主键(primary key)

    每个 entity 必须至少定义一个成员作为主键。也就是说,当仅有一个成员的时候,需要使用 @PrimaryKey 对该成员进程注解。如果你希望 Room 给 entity 设置一个自增的 id , 可以设置 @PrimaryKey 的 autoGenerate 属性。如果一个 entity 需要复合主键(译注:多个字段共同构成主键,主要是考虑到没有id作为你主键,但是又要保证主键唯一性的问题),你可以使用 @Entity 注解的 primaryKeys 属性。

    @Entity(primaryKeys = {"firstName", "lastName"})
    class User {
        public String firstName;
        public String lastName;
    
        @Ignore
        Bitmap picture;
    }
    
    @Entity
    public class User {
        @PrimaryKey(autoGenerate = true)
        private int uid;
    
        @ColumnInfo(name = "first_name")
        private String firstName;
    
        @ColumnInfo(name = "last_name")
        private String lastName;
    
        // Getters and setters are ignored for brevity,
        // but they're required for Room to work.
    }
    

    默认情况下, Room 将使用类名作为 table 的名字,当然,你也可以自己设定名字:

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

    注意,table 名字在 SQLite 中是大小写不敏感的。
    类似于上面的 tableName 属性,Room 默认使用成员名作为列名,当然,你也可以通过 @ColumnInfo 自己设定:

    @Entity(tableName = "users")
    class User {
        @PrimaryKey
        public int id;
    
        @ColumnInfo(name = "first_name")
        public String firstName;
    
        @ColumnInfo(name = "last_name")
        public String lastName;
    
        @Ignore
        Bitmap picture;
    }
    

    注解索引和设置唯一性

    为了在 entity 中建立索引,需要在 @Entity 注解中添加 indices 属性,列出需要索引的列名。

    @Entity(indices = {@Index("name"),
            @Index(value = {"last_name", "address"})})
    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。

    @Entity(indices = {@Index(value = {"first_name", "last_name"},
            unique = true)})
    class User {
        @PrimaryKey
        public int id;
    
        @ColumnInfo(name = "first_name")
        public String firstName;
    
        @ColumnInfo(name = "last_name")
        public String lastName;
    
        @Ignore
        Bitmap picture;
    }
    

    定义对象之间的关系

    SQLite 是一种关系型数据库。你可以指定 对象 之间的关系。虽然很多 ORM 库(对象关系映射库)允许 entity 对象相互引用,但是这在 Room 是明确禁止的。
    即使你不能直接使用这些直接关系,但是 Room 允许你定义在 entity 之间的外键。
    举个栗子,假如这里有另外一个叫做 Book 的 entity,你可以通过 @ForeignKey 定义它和 User 实体的关系。

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

    外键是很强大的,它们允许你指定 当引用的 entity 发生更新的时候会发生什么。比如,你可以通过在 @ForeignKey 注解中,添加 onDelete = CASCADE ,以告诉SQLite,如果一个 User 实体被删除的时候,删除他所有的书籍。

    创建嵌套对象

    以上,我们在成员都是基础类型或者 string 类型的数据。 但是有时,在逻辑上,我们希望将某某些成员封装一个紧密结合的内部实体。此时可以使用 @Embedded 注解表达这一类内部嵌套的实体。
    在进行查询访问的时候,内部实体的每个成员还是需要作为一个单独的列来访问它们。

    class Address {
        public String street;
        public String state;
        public String city;
    
        @ColumnInfo(name = "post_code")
        public int postCode;
    }
    
    @Entity
    class User {
        @PrimaryKey
        public int id;
    
        public String firstName;
    
        @Embedded
        public Address address;
    }
    

    上述表中,有一下列:id, firstName, street, state, city, and post_code。
    注意,嵌套之中还可以添加嵌套。
    如果在 entity 中包含多个同类型的嵌套,这时候可以通过设置 prefix 属性的方式加以区分:

    @Embedded(prefix = "addr1")
    public Address address1;
    @Embedded(prefix = "addr2")
    public Address address2;
    

    Room 会把这个 prefix 作为前缀添加到每个列名前面。
    (译注:通过insert方法插入嵌套结构数据之后示意图如下)

    db.userDao().insertAll(user)

    相关文章

      网友评论

        本文标题:[译] 通过 Room entities 定义数据 ---Roo

        本文链接:https://www.haomeiwen.com/subject/aiboixtx.html