Earth Guardian

You are not LATE!You are not EARLY!

0%

greenDao

介绍

greenDao 是一个将对象映射到 SQLite 数据库中的轻量且快速的 ORM 解决方案

greenDAO is an open source Android ORM making development for SQLite databases fun again. greenDAO frees you from these by mapping Java objects to database tables (called ORM, “object/relational mapping”).
官网 , github

对象关系映射 ORM

ORM: Object Relational Mapping 对象关系映射,是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换,主要解决对象-关系的映射

面向对象概念 面向关系概念
对象 表的行
属性 表的列

ORM 的思想:将关系数据库中表中的记录映射成为对象,以对象的形式展现,程序员可以把对数据库的操作转化为对对象的操作

依赖

需要添加三个地方,见如下注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// In your root build.gradle file:
buildscript {
repositories {
jcenter()
mavenCentral() // add repository
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
}
}

// In your app projects build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin

dependencies {
compile 'org.greenrobot:greendao:3.2.2' // add library
}

基本概念

DaoMaster

整个 greenDao 的入口,持有数据库对象(SQLiteDatabase),可以创建和删除表,它的内部类 OpenHelperDevOpenHelperSQLiteOpenHelper 的实现。

DaoSession

管理所有的 Dao 对象,实现所有的增删改查等功能。

Daos

Daos: Data access objects 数据访问对象,greenDao 为每个 Entity 都会创建一个 Dao,常见的增删改查都是在 Dao 中进行的。

Entities

类似数据库的一张表。

联系图:

0016-greenDao-greenDao_Core-Classes.png

Schema

app/build.gradle 中添加 Schema 配置:

1
2
3
greendao {
schemaVersion 1
}

支持如下参数:

  • schemaVersion
    数据库 schema 版本号,如果数据库或者表相关有修改或迁移,需要增加该值
  • daoPackage
    dao 源码的包名,默认为 entity 代码所在目录
  • targetGenDir
    greenDao 生成代码的目录地址,默认: build/generated/source/greendao
  • generateTests
    自动产生带有测试目录
  • targetGenDirTests
    单元测试源码地址,默认:src/androidTest/java

常见流程

创建实体类 Entity

类名需要使用 @Entity 标注,主键使用 @Id 标注,必须使用 long/Long 类型。如果是 Long 类型,主键是由 greenDao 维护的,类似自增长(允许之前删掉了的 id 重复使用,所以需要注意 id 相同但实际内容已经改变),我们不需要手动修改;如果是 long 类型,需要代码中主动赋值,否则默认为 0 导致插入时抛出重复错误异常

1
2
3
4
5
6
7
@Entity
public class Fun {
@Id
private Long id;
private String author;
...
}

Entity 标注的类,如果有属性字段修改,必须重新编译一次生成对应的构造函数及 setter/getter

编译工程

AS 中点击编译工程,greenDao 自动生成对应文件:

  • Entity 标注的类,自动生成构造函数,setter/getter
  • DaoMaster,DaoSession 等辅助类,方便后续编码时调用

实例化 DaoSession

  • 创建 DbHelper,初始化数据库,处理数据库升级等等
  • 构造函数中实例化一个 DaoSession,通过该实例来做增删改查等相关操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class DbHelper extends DaoMaster.OpenHelper{

private static final String DATABASE_NAME = "FunReading.db";
private static final boolean ENCRYPTED = false;
private DaoSession mDaoSession;

public DbHelper(Context context){
super(context, DATABASE_NAME);
Database db = ENCRYPTED ? getEncryptedWritableDb("super-secret") : getWritableDb();
mDaoSession = new DaoMaster(db).newSession();
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
}

public DaoSession getDaoSession(){
return mDaoSession;
}

}

注意:DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失,只能在开发调试的时候使用

增删改查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// DaoSession 或者 通过 DaoSession 拿到 Dao 后,做增删改查
FunDao funDao = mDaoSession.getFunDao();
// 1. 增
funDao.insert(fun); // 单条
funDao.insertInTx(funList); // 批量

// 2. 删
funDao.deleteByKey(fun.getId()); // 单条
funDao.deleteByKeyInTx(idList); // 批量
funDao.deleteAll(); // 所有

// 3. 改
funDao.update(fun); // 单条
funDao.updateInTx(funList); // 批量

// 4. 查
funDao.load(id); // 单条
funDao.loadAll(); // 所有
funDao.queryRaw(...); // 支持 sql 原始查看方式
// 条件查询,where 条件与
funDao.queryBuilder().where(where).build().list();
// 条件或
funDao.queryBuilder().whereOr(where).build().list();

注解

实体对应表

  • @Entity 定义实体
  • @nameInDb 在数据库中的名字,如不写则为实体中类名
  • @indexes 索引
  • @createInDb 是否创建表,默认为true,false时不创建
  • @schema 指定架构名称为实体
  • @active 无论是更新生成都刷新
  • @Property(nameInDb = "USERNAME")
    标准字段对应数据库中的字段名,也就是java的字段熟悉命名可以和数据库字段命名不一致,但是要通过该注解转换

    其他

  • @Id
  • @NotNull 不为null
  • @Unique 表示该字段唯一
  • @ToMany 一对多
  • @OrderBy 排序
  • @ToOne 一对一
  • @Transient 不存储在数据库中
  • @generatedgreendao 产生的构造函数或方法

常见问题

重复 Id 无法新增数据

android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: FUN._id (code 1555)
出现这种情况可以设置主键为 Long 类型,让 greenDao 自动增长主键,避免出现字段不唯一报错

数据类型不支持

1
2
Error:Execution failed for task ':app:greendao'.
Can't add property 'Variable(type=VariableType(name=com.***.funreading.model.DataType, isPrimitive=false, originalName=DataType, typeArguments=null), name=type)' to entity Fun due to: Unsupported type com.***.funreading.model.DataType`

不能保存自定义数据类型

参考文档:

  1. http://blog.csdn.net/fesdgasdgasdg/article/details/51835699
  2. http://www.open-open.com/lib/view/open1438065400878.html
  3. greenDAO3基本使用
  4. greenDao进阶
  5. GreenDao3.0简单使用
  6. GreenDao 使用教程
  7. GreenDao3 使用说明
  8. 查询进阶