greenDAO使用总结

概况

此文档主要描述greenDAO 3的相关概念及使用,包括项目中的配置、数据操作(增删改查)等。

配置

与greenDAO 2的区别

greenDAO 2(之前的版本)需要开发者在工程中另建一个独立的Java生成器项目(需要使用到“greendao-generator”依赖,来自动生成greenDAO需用的代码),然而greenDAO 3只需使用注解定义实体类,然后通过gradle插件就可以生成代码

greenDAO 3的配置

添加gradle插件到buildscript

在工程的build.gradle文件中添加gradle插件到buildscript块中

1
2
3
4
5
buildscript {
dependencies {
classpath ‘org.greenrobot:greendao-gradle-plugin:3.0.0’
}
}

根模块中使用gradle插件

在根模块的build.gradle文件中使用gradle插件

1
2
3
4
5
apply plugin ‘org.greenrobot.greendao’
dependencies {
compile ‘org.greenrobot:greendao:3.0.1’
}

gradle插件的配置

在根模块的build.gradle文件中配置greendao

1
2
3
4
5
greendao {
schemaVersion 2
daoPackage ‘…’
targetGenDir ‘…’
}
  1. schemaVersion:指定数据库schema的当前版本号,被*OpenHelpers类使用,用于在不同的schema版本号之间迁移,如果修改了Entity或数据库的schema,该值必须增加,默认是1
  2. daoPackage:用于存放生成的DAODaoMasterDaoSession的包名,默认是源Entities的包名
  3. targetGenDir:生成的源码应存放的位置,默认是build目录下的generated文件夹下(build/generated/source/greendao
  4. generateTests:设置为true时自动生成单元测试代码
  5. targetGenGenTest生成单元测试代码的存放位置

Gradle插件实现步骤

每次在make工程时,Gradle插件会扫描工程中所有的@Entity文件(greenDAO用到的数据库实体类),并根据实体类生成DaoMasterDaoSession以及所有实体类的DAO类,生成的文件默认目录为build/generated/source/greendao

基本概念

@Entity

@Entity注解标记一个Java类为持久的实体,可以配置如下参数

  1. schema告诉greenDAO该实体属于哪个schemaNote:当使用Gradle插件时目前不支持多个schemas)
  2. active标记一个Entity的激活状态,激活的Entity有更新/删除/刷新方法
  3. nameInDb指定表在数据库中的名称,默认是实体的类名
  4. indexes定义跨越多列的索引
  5. createInDb标记greenDAO是否创建数据库表,默认为true。如果有多个实体映射到同一个表,或者表在greenDAO外面创建了,可以设置为false

基本属性注解

  1. @Id选择一个long/Long类型的属性作为实体ID。在数据库里,它是主键(PK)。参数autoincrement是一个让ID值增加的标记(不重用旧值)
  2. @Property定义一个属性映射的非默认的列名,如果如果不指定,greenDAO默认以SQL-ish的形式使用域名,即大写、下划线代替驼峰,如customName会变成CUSTOM_NAME
  3. @NotNull:让属性在数据库里成为一个“NOT NULL”
  4. @Transient让属性不被存入持久层

索引注解

  1. @Index为一个数据库列创建一个数据库索引
    • name如果不喜欢greenDAO生成的默认索引名,可以通过该字段指定
    • unique:为该索引添加一个UNIQUE限制,强制所有值是唯一的
  2. @Unique:为一个数据库列添加一个UNIQUE限制。注意SQLite也默认创建了一个索引

关联注解

  1. @ToOne定义与另一个实体的关联,应用该注解到有另一个实体对象的属性上。在内部,greenDAO需要一个额外的指向目标实体的属性,通过joinProperty参数来指定。如果没有该参数,一个额外的列会被自动创建并拥有此KEY
  2. @ToMany定义与多个实体的关联,应用该注解到一组目标实体的属性上。目标实体必须有一个或多个指向源Entity的属性。有三种可能(只能使用其中一种)指定关联的映射
    • referencedJoinProperty:指向目标Entity的ID的外键(FK)属性名
    • joinProperties:为了更多复杂的关联,可以指定一组@JoinProperty注解。每个@JoinProperty需要一个源Entity的属性和目标Entity的属性
  3. @JoinEntity如果一个多对多的关联有另一个entity/table,可以在该属性上添加该注解

@Generated

在greenDAO 3中Entity类由开发者创建和编辑,在代码生成过程中,greenDAO会增加实体的源码,同时会添加@Generated注解到生成的方法和域上来提示开发者,为了阻止任何代码的丢失。在大多数情况下,开发者不应该接触带有@Generated注解的代码。作为预防措施,greenDAO不会重写存在的代码,如果生成的代码被手动修改了,greenDAO会报错。

使用

编写Entity类

App.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Entity(nameInDb = "app")
public class App {
@Id
private Long id;
@NotNull
private String appUuid;
@NotNull
private String name;
@NotNull
private String iconUrl;
private int type;
}

City.java

1
2
3
4
5
6
7
8
9
10
11
12
@Entity(nameInDb = "city")
public class City {
@NotNull
private String name;
@NotNull
private String code;
@Id
private Long id;
}

JoinCityToApp.java

1
2
3
4
5
6
7
8
9
10
@Entity
public class JoinCityToApp {
@Id
private Long id;
private Long cityId;
private Long appId;
}

CityInfo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Entity(nameInDb = "city_info")
public class CityInfo {
@Id
private Long id;
@NotNull
private String name;
@NotNull
private String code;
@ToMany
@JoinEntity(
entity = JoinCityToApp.class,
sourceProperty = "cityId",
targetProperty = "appId"
)
private List<App> appList;
}

增删改查操作

初始化数据库

获取DaoMaster.DevOpenHelper的实例即可

1
DaoMaster.DevOpenHelper mHelper = new DaoMaster.DevOpenHelper(context, DB_NAME);

增加操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void insertCityInfo(CityInfo info, List<App> appList, List<Banner> bannerList) {
DaoSession daoSession = new DaoMaster(getWritableDatabase()).newSession();
long infoId = daoSession.insert(info);
JoinCityToApp joinCityToApp = null;
for (App app : appList) {
long appId = daoSession.insert(app);
joinCityToApp = new JoinCityToApp(null, infoId, appId);
daoSession.insert(joinCityToApp);
}
JoinCityToBanner joinCityToBanner = null;
for (Banner banner : bannerList) {
long bannerId = daoSession.insert(banner);
daoSession.insert(banner);
joinCityToBanner = new JoinCityToBanner(null, infoId, bannerId);
daoSession.insert(joinCityToBanner);
}
}

查询操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public List<App> queryAppList(String code) {
List<App> list = null;
DaoSession daoSession = new DaoMaster(getWritableDatabase()).newSession();
Query query = daoSession.getCityInfoDao().queryBuilder()
.where(CityInfoDao.Properties.Code.eq(code))
.build();
List<CityInfo> infoList = query.list();
if (null != infoList && infoList.size() > 0) {
list = new ArrayList<>();
for (CityInfo info : infoList) {
list.addAll(info.getAppList());
}
}
return list;
}

参考方案

  1. Updating to greenDAO 3 and annotations
  2. greenrobot/greenDAO
  3. 【greenDAO 3】项目搭建与增删该查操作
  4. greenDAO Features