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,异步操作更高效
长按识别下方二维码,加入我的知识星球,一起学习和交流
领取专属 10元无门槛券
私享最新 技术干货