要在一个项目里使用greenDAO,你需要创建一个代表应用程序中持久化数据的实体模型。然后,基于这个模型,greenDAO会为DAO类生成Java代码。
这个模型本身被带注解的Java类定义。
要是用老式的生成器方法创建你的模式,请参阅生成器。
右边的插图描绘了greenDAO基于的原模型。
不需要任何额外的配置,你就可以通过greenDAO gradle插件来开始。即便如此,你至少应该考虑设置模式版本:
// In the build.gradle file of your app project:
android {
...
}
greendao {
schemaVersion 2
}
而且,greenDAO配置的元素支持很多配置选项:
OpenHelpers
类通过这个来实现模式版本之间迁移。如果你修改了实体或者数据库的模型,这个数值应该被增大。默认值时1.build/generated/source/greendao
)。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让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关键字。
当下,所有实体都必须有一个long
或Long
属性作为它们的主键。这源自Android和SQLite的最佳实践。
围绕这个,你可以把你这个主键定义为一个额外的属性,但是为它创建一个唯一的索引。
@Id
private Long id;
@Index(unique = true)
private String key;
使用@Index在数据库相对应的属性创建一个数据库索引。用下面这些参数可以自定义:
@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”来触发代码生成进程,或者直接执行greendao
Gradle任务。
如果更改了你的实体类之后遭遇到了错误提示,尝试重新构建你的项目来保证那些旧的生成代码被清除掉。
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.
正如这个错误信息的暗示,通过有两个方法解决它:
KEEP
部分在老版本的greenDAO中被使用,现在已经不支持了。
尽管如此,如果Gradle插件察觉一个KEEP FIELDS
部分,它会自动在这个字段里使用@Transient的注解。之后,KEEP FIELDS
周围的评论可能会被移除掉。
原文档在这里,欢迎指正。