本文链接: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
10buildscript {
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
2apply 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 使用详解(进阶篇)