本文链接:https://rainmonth.github.io/posts/A211027.html
Android greenDAO使用参考内容:官方网站,打开官网发现官网极力推荐ObjectBox使用,后面会对ObjectBox页做一个简单的说明。
摘要
greenDAO是一款开源高效的ORM数据库,极大的降低开发者编写sql查询的时间(使用greenDAO后会自动生成对应的dao,可以进行CRUD操作)。而greenDAO的使用也极其简单。greenDAO具有以下特点:
- 性能好,特别是在Android平台上(相对于其他的ORM框架来说)表现尤其出色;
- 易用,提供了强大的API;
- 内存消耗小;
- 库体积小;
- 支持数据库加密,greenDAO支持SQLChiper
- 社区强大
ORM
ORM,即对象关系映射(Object-Relationship Mapping),具有以下特点:
- 简单,ORM可以将SQLite(或MySql)的一张表映射成一个Java对象;
- 精确,所有的数据表都按统一的标准映射成Java对象;
- 易懂,ORM是数据库结构文档化,一张张表对Java程序员来说就是一个个实体类;
- 易用,ORM包含了对生成Java持久化数据对象的一些列CRUD操作,风格统一,规范,便于维护;
参考:ORM框架简介
基本使用
配置greedDAO环境
- 根目录的build.gradle添加如下代码: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10- buildscript { 
 repositories {
 jcenter()
 mavenCentral() // 添加仓库地址
 }
 dependencies {
 classpath 'com.android.tools.build:gradle:3.5.3'
 classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0' // 添加插件
 }
 }
- 应用module的build.gradle文件添加如下代码 - 1 
 2- apply plugin: 'com.android.application' 
 apply plugin: 'org.greenrobot.greendao' // apply plugin
dependencies {
    implementation ‘org.greenrobot:greendao:3.3.0’ // add library
}
| 1 | 3. greenDAO的一些配置 | 
基础注解说明
- @Entity,加在类上,声明表的实体类型,加上给注解后会根据类的属性生成必要的表,字段就是类的属性;该注解有如下属性 - nameInDb, 表在数据库中的别名,不指定默认就是实体类名;
- Index[],索引,可以跨列;
- createInDb,默认true,标记在数据库中刚创建表;
- schema,表的schema;
- active,默认为true,实体(表)是否处于活跃状态,活跃状态的有更新删除和刷新的方法;
- generateConstructors,默认true,是否生成构造函数;
- generateGettersSetters,默认true,标记是否生成相应的get/set方法;
- protobuf,默认为void.class,为实体类提供一个额外的class以生成一个特殊的DAO
 
- @Id,加载实体类的属性上,定义自增id,有一个autoincrement属性,默认为false; 
- @Index,加载实体类属性上,表示索引,有value、name、unique三个属性; 
- @Generated,表明是属性、方法或构造方法是由greenDAO自己生成的代码; 
- @JoinEntity,用于建立多对多关系 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 public class Product {
 private Long id;
 
 
 private List ordersWithThisProduct;
 }
 public class JoinProductsWithOrders {
 private Long id;
 private Long productId;
 private Long orderId;
 }
 public class Order {
 private Long id;
 }
| 1 | - @JoinProperty,用来定义Join的的两个属性分别是name和referenceName | 
- @Transient,不会被greenDAO持久化到数据库中;
- @Unique,创建表的时候被@Unique注释的属性需遵循唯一性约束;
实体类支持的字段类型
greenDAO默认支持的字段类型有如下:
| 1 | boolean, Boolean | 
核心类
greenDAO 使用是否简单,在使用@Entity注解定义好实体后,编译就可以自动生成一些用来进行数据库操作的处理。正常的主要类有DaoMaster、DaoSession、XxxEntity
DaoMaster
负责管理数据库对象和EntityDAO对象的关系,可以通过其内部类OpenHelper、DevOpenHelper、SQLiteOpenHelper创建不同模式的数据库。负责表的创建、更新,负责数据库的升级,负责DaoSession的创建
DaoSession
管理者所有的EntityDAO,提供了公用的实体CRUD方法(实际上是在AbstractDAOSession中实现的)
XxxEntity
根据定义的java类(@Entity注解修饰的类)生成的类文件,会根据@Entity注解的属性按需生成类方法(如是否需要生成构造函数,是否需要生成getter/setter方法等。
原理
由于greenDAO是一个ORM框架,干的就是对象关系映射这件事,所以要搞清楚对象到关系的映射是如何生成的。这里原理分析部分主要分析代码自动生成,这样以后自己也可以写插件自动生成代码了。
- greenDAO的api就是其定义的那些注解,开发者在原始的类中根据要在数据库中建立的表的关系,将api(即注解应用上去),这样开发者的工作就完成了,箱单简单;
- 前面在介绍基本使用时,在项目的根目录下的build.gradle引用了gradle插件org.greenrobot:greendao-gradle-plugin:3.3.0,并在app Module中的build.gradle文件作用应用了插件apply plugin: 'org.greenrobot.greendao'。注意应用这个插件的目的就是为了让greenDAO在编译能找到合适的时机来进行相关的代码生成。这说明两点:- greenDAO的gradle插件只是为greenDAO生成代码找一个切口,跟greenDAO代码生成是没有直接联系的;
- 生成代码是在编译期进行的,所以greenDAO并不会影响app运行时的效率,但是会影响apk的编译速度。(实际项目中可以采用demo工程生成相关代码,然后将代码拷贝到实际的工程中来,这样就避免了这一影响)
 
- 有一个控制模块:greendao-code-modifier,它来控制greenDAO的代码生成,具体包括:- 收集注解信息并判断注解信息是否要更新(收集注解信息采用的greendao-jdt,由此可见greenDAO采用的注解处理器是JDT,与常见的注解处理方法(APT、反射不同)
- 调用greenDAO的code-generator来进行代码,code-generator使用的代码生成模板为FreeMarker;
 
- 然后就得到了开发者实际运行时用到的几个核心类:DaoMaster、DaoSession、XxxEntity;
- greenDAO-core通过4中生成的三中核心类来跟SQLite进行交互。
用到的技术
- gradle插件技术,gradle插件开发介绍:https://www.jianshu.com/p/d53399cd507b;
- Android注解相关技术
- JDT注解处理与收集,JDT介绍:http://www.eclipse.org/jdt/overview.php
- 代码生成框架FreeMaker,FreeMarker快速入门:https://segmentfault.com/a/1190000011768799
greeDAO 数据库升级
为什么会要单独拎一节来讲数据库升级呢?首先,面试中经常会被问到,哈哈;其次这个是开发中很容易遇到的问题,下面来介绍下。
greenDAO的数据库升级处理主要是在DaoMaster中进行的,主要是:
| 1 | /** | 
当我们数据表发生更改的时候,我们需要在app的build.gradle下的greendao{}升级schemaVersion版本,版本改变后,最终就会走到onUpgrade(...)里面。
粗暴的策略:删掉所有老的表,然后创建新的,然后所有的数据都丢了,然后该滚蛋了…….
通常的升级策略
- 针对有索引的表,先要删除相应的索引,否则数据备份是会存在冲突;
- 针对有变动的表,将原来的老表重命名为相应的临时表(改变表明);
- 创建新表
- 数据恢复,将临时表的数据恢复到新表中(新表临时表都包含的字段需要恢复)
- 删除临时表;
- 保底措施:如果表没出创建成功,重新创建
greenDAO降级处理
降级处理比较简单,删除表然后重新创建
| 1 | 
 | 
疑问
- 不定义主键会发生什么? 
- SqlLite数据库操作需要加锁吗? 
- SqlLite数据库不同字段的限制条件是什么? 
小结
了解了greenDAO的基本使用,特点及性能情况,同时对greenDAO整体的处理流程做了一个梳理,至于具体每个流程,如插件编写、注解处理、FreeMarker的具体使用细节,后面有机会单独介绍,这里不做赘述。
本文知识greenDAO的基本使用及原理介绍,高级使用请移步Android ORM 框架:GreenDao 使用详解(进阶篇)