GreenDao源码分析

GreenDao源码分析

简述

DaoMaster、具体的Dao 和 DaoSession对象为greedao生成的代码

从平时的使用可以看出他们的作用

DaoMaster

DaoSession

xxEntity

xxDao

这几个类的关系如下UML图:

Dao对象需要依赖DaoConfig对象

DaoConfig对象需要传入具体的DaoClass类型

获取DAO里面的Properties 所有static或者public字段

这里会获取所有的数据库字段,顺便判断表主键是否是数字类型

数据库加密

GreenDAO创建会话的时候我们一般会调用如下代码获取DaoSession对象:

在AbstractDAO类中,有一个db字段,最终的数据库操作以及事务的开启都会通过这个对象开启。GreenDAO中存在Database和DatabaseStatement2个接口

这2个接口分别存在2个子类StandardDatabase、EncryptedDatabase 和 StandardDatabaseStatement 、EncryptedDatabaseStatement,这几个类其实都是一个代理模式

这里会发现GreenDAO调用了一个三方库叫做sqlcipher.,提供了Sqlite的数据库加密功能。所以GreenDAO在创建一次会话的时候可以指定数据库是否加密。如果没加密,会使用Android的Sqlite API去操作数据库,如果加密,则使用sqlcipher提供发API去操作数据库。

GreenDAO的增删改查

GreenDAO通过AbstractDAO类实现数据库的增删改查逻辑,此处分析几个常用的方法

insert 插入数据

内部逻辑伪代码:

update 更新数据

update的源码大概为

关注updateInsideSynchronized方法

和insert方法类似,添加了主键判断必须存在key的逻辑

其中添加了

这个index bind的字段是update的条件语句,和id进行绑定

换成sql语句就是

select 查询操作

查询的代码和insert、update大致流程一致

会通过QueryBuilder构造查询条件,在QueryBuilder中list方法获取数据

会走到AbstractDao类的loadAllFromCursor方法

会走到loadCurrent方法

此处可以关于IdentityScope的代码

delete 删除的逻辑和增改查大致一样

GreenDAO缓存

在上面query的源码中可以发现GreenDAO对于数据做了一次内存的缓存,每次写数据库的时候会从IdentityScope的map 中put一次数据。每次读数据库的时候会从IdentityScope的map中get一次数据。如果map中缓存拿到了,就使用缓存作为查询的结果。

在查询和更新数据的时候会执行

方法,具体逻辑如下

GreenDAO的异步操作

有些时候,我们希望异步的操作数据库,GreenDAO给我们提供了异步的方法。

大致用法为:

我们获取一个AsyncSession对象进行异步的数据库操作,并且可以设置AsyncOperation对异步操作进行监听。但是为什么所有的异步操作是同一个Listener回调呢?我们可以在源码中找到答案。

查看AsyncSession的insert方法

最后可以走到enqueEntityOperation方法

可以发现有一个异步操作的Executor,AsyncOperationExecutor

查看enqueue方法

可以看到它把异步加入到一个队列里面排队等待。在线程池中执行这些操作。

查看run方法

这段代码我们可以看到,每次从队列中拿一个异步操作对象执行逻辑。这也解释了为什么外层只需要set一个Listener。GreenDAO的异步操作是所有的数据库操作在一个子线程中进行同步操作。

最终代码会走到executeOperation方法

这里会执行具体的DAO对象的数据库操作方法。

和ReactiveX的结合

GreenDAO提供了API与rxjava结合使用,代码如下:

我们来简单分析下源码看看RxJava是如何和GreenDAO结合的

查看AbstractDAO的rx()

查看RxDAO的构造方法

包含了Dao对象和线程调度Scheduler对象,这里是io线程,即在异步线程执行

查看insert方法

查看wrap方法, wrap方法里面也调用了一个重载的wrap方法。

参数为一个Callable对象,里面执行了数据库插入的逻辑,返回了实体类对象。

这里的第二个wrap方法的参数observable是通过RxUtils.fromCallable获得的,查看这个方法的源码

这里使用了defer操作符创建一个Observable对象。延迟创建,确保Observable被订阅后才执行。

以上就是rxjava和GreenDAO的结合使用的原理。和rx'java结合使用,会使GreenDAO尤其是异步操作写起来更加的优雅。

GreenDAO代码生成

我们在GreenDAO使用的时候,会自动生成DaoMaster,DAO对象等等java文件。大致翻阅了DaoGenerator这个Module里面的代码。发现有模板引擎的库依赖:

并且发现了freemarker的模板文件

在DaoGenerator/src-template里面,有很多的.ftl文件。GreenDAO的文件就是通过freemarker模板生成的Java文件。具体的原理下次分析后会单独再写一篇博客。

总结

通过对GreenDAO的源码分析,可以发现GreenDAO号称自己是性能最好的ORM库也是有原因的,GreenDAO的特点总结为以下:

使用了静态代码生成,不通过反射运行时生成代理类,提升了性能

使用了SQLiteStatement

同时提供了同步和异步的数据库操作方式

数据库提供内存缓存,更高效的查询

基于sqlcipher提供加密数据库

提供RxJava的API,异步操作更高效

长按识别下方二维码,加入我的知识星球,一起学习和交流

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180408G09C2A00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券