greenDAO文档翻译之三:模型化实体

要在一个项目里使用greenDAO,你需要创建一个代表应用程序中持久化数据的实体模型。然后,基于这个模型,greenDAO会为DAO类生成Java代码。
这个模型本身被带注解的Java类定义。

要是用老式的生成器方法创建你的模式,请参阅生成器


右边的插图描绘了greenDAO基于的原模型。

模型

不需要任何额外的配置,你就可以通过greenDAO gradle插件来开始。即便如此,你至少应该考虑设置模式版本:

// In the build.gradle file of your app project:
android {
...
}

greendao {
    schemaVersion 2
}

而且,greenDAO配置的元素支持很多配置选项:

  • schemaVersion:数据库模式的当前版本。OpenHelpers类通过这个来实现模式版本之间迁移。如果你修改了实体或者数据库的模型,这个数值应该被增大。默认值时1.
  • daoPackage:这个包名是为生成的DAO类、DaoMaster和DaoSession而准备。默认的包名是你的实体类源码所在的位置。
  • targetGenDir:生成的源码存放的位置。默认生成的源码文件夹是在build路径下(build/generated/source/greendao)。
  • generateTests:设置为true会自动生成单元测试代码。
  • targetGenDirTests:存储生成的单元测试代码的基础路径。默认是src/androidTest/java
实体和注解

greenDAO3使用注解来声明模型和实体类。下面是一个简单例子:

@Entity
public class User { 
    @Id
    private Long id; 

    private String name;

    @Transient
    private int tempUsageCount; // not persisted 
    // getters and setters for id and user ...
}

@Entity注解把User这个Java类转换为数据库支持的实体。它同样会指示greenDAO生成必要的代码(例如DAO类)。

注意:注解仅支持Java类。如果你更中意于其他的编程语言,像Kotlin,你的实体类仍然必须是Java实现。

@Entity注解

正如你在上面的例子中看到的,@Entity让Java类变成了可为greenDAO持久化的实体。

使用@Entity注解通常不使用用任何额外的参数已经足够好了,你仍然可以配置一些细节:

@Entity(
        // If you have more than one schema, you can tell greenDAO
        // to which schema an entity belongs (pick any string as a name).
        schema = "myschema",

        // Flag to make an entity "active": Active entities have update,
        // delete, and refresh methods.
        active = true,

        // Specifies the name of the table in the database.
        // By default, the name is based on the entities class name.
        nameInDb = "AWESOME_USERS",

        // Define indexes spanning multiple columns here.
        indexes = {
                @Index(value = "name DESC", unique = true)
        },

        // Flag if the DAO should create the database table (default is true).
        // Set this to false, if you have multiple entities mapping to one table,
        // or the table creation is done outside of greenDAO.
        createInDb = false,

        // Whether an all properties constructor should be generated.
        // A no-args constructor is always required.
        generateConstructors = true,

        // Whether getters and setters for properties should be generated if missing.
        generateGettersSetters = true
)
public class User {
  ...
}

注意使用gradle插件的话目前还不支持多个模式。暂时来讲,还是继续用你的生成器项目吧。

基本属性
@Entity
public class User {
    @Id(autoincrement = true)
    private Long id;

    @Property(nameInDb = "USERNAME")
    private String name;

    @NotNull
    private int repos;

    @Transient
    private int tempUsageCount;

    ...
}

@Id这个注解会选择一个long或者Long属性来作为实体的ID。在数据库的角度看,这就是主键。参数autoincrement则是标记了ID值会一直增长 (而不是使用旧的值)。

@Property让你可以自定义一个列的名字,而不是使用默认的,与这个属性映射。如果没有设置,greenDAO将会按照SQL的样式使用这个字段名字(大写字母、下划线取代驼峰,例如customName就会变成CUSTOM_NAME)。注意:你当前只能使用内部常量置顶一个列的名字

@NotNull让数据库的列拥有了“非空”属性。通常有意义的做法是在基础数据类型(long, int, short, byte)上用@NotNull做标记,对应它们可为空的包裹类(Long, Integer, Short, Byte)。

@Transient标记排除持久化的属性。把它用在维持短暂状态的数据上,等等。或者,你也可以使用Java中的transient关键字。

主键限制

当下,所有实体都必须有一个longLong属性作为它们的主键。这源自AndroidSQLite的最佳实践。

围绕这个,你可以把你这个主键定义为一个额外的属性,但是为它创建一个唯一的索引。

@Id
private Long id;

@Index(unique = true)
private String key;
属性索引

使用@Index在数据库相对应的属性创建一个数据库索引。用下面这些参数可以自定义:

  • name:如果你不喜欢greenDAO默认为你生成的索引名字,你可以在这里自定义。
  • unique:给索引添加一个唯一限制,强制所有的数值都是唯一的。
@Entity
public class User {
    @Id private Long id;
    @Index(unique = true)
    private String name;
}

@Unique属性给数据库的列添加了一个唯一性限制。注意,SQLite也会隐式地为它创建一个索引。

@Entity
public class User {
    @Id private Long id;
    @Unique private String name;
}
默认

greenDAO努力在明知地默认情况下工作,所以开发者不用必须配置每一处细节。

举个例子数据库中的表名和列名是来源于实体和属性的名字。不像Java中使用的驼峰风格,默认的数据库名字是大写字母,使用下划线分割字母的。

例如,一个creationDate的属性,会变成数据库中的列的名字会是CREATION_DATE

关系

要学习如何添加对一或者对多关系,请看关系

触发生成

一旦你的实体模型准备就位了,你可以在你的IDE中通过“Make project”来触发代码生成进程,或者直接执行greendaoGradle任务。

如果更改了你的实体类之后遭遇到了错误提示,尝试重新构建你的项目来保证那些旧的生成代码被清除掉。

修改生成的代码

greenDAO3种的实体类由开发者创建和编辑。无论如何,代码生成进程中greenDAO可能会增加实体的源代码。

greenDAO会在它所创建的方法和字段上添加@Generated注解来告诉开发者并防止任何代码的丢失。大多数情况下,你没有必要去触碰被@Generated注解的代码。

作为一个预防措施,greenDAO不会复写已经存在的代码,并且人工更改生成的代码也会增加一个错误。

Error:Execution failed for task ':app:greendao'.
> Constructor (see ExampleEntity:21) has been changed after generation.
Please either mark it with @Keep annotation instead of @Generated to keep it untouched,
or use @Generated (without hash) to allow to replace it.

正如这个错误信息的暗示,通过有两个方法解决它:

  • 还原掉对那些被@Generated注解的代码修改。或者,你还可以完全地删除被修改的构造方法或其他方法。下次构建的时候它们会被重新生成。
  • 使用@Keep注解代替@Generated。这会告诉greenDAO永远不要触碰被注解的代码。时刻铭记你的修改会破坏实体和greenDAO其他地方的协议。同时,greenDAO未来的稳定版本预计在生成的方法会是不同的代码。所以,一定要注意!及时的单元测试来避免麻烦是个好主意。
Keep部分

KEEP部分在老版本的greenDAO中被使用,现在已经不支持了。

尽管如此,如果Gradle插件察觉一个KEEP FIELDS部分,它会自动在这个字段里使用@Transient的注解。之后,KEEP FIELDS周围的评论可能会被移除掉。


原文档在这里,欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值