Android-GreenDao增删改查以及底层实现简介

GreenDao 初始化:

public voidinitDB(Context context,String dbName)

{

this.context= context;

DaoMaster.DevOpenHelper helper =newDaoMaster.DevOpenHelper(context,"name_jia_"+ dbName, null);

instance.sqlDb= helper.getWritableDatabase();

instance.cx_jia_daoMaster=newDaoMaster(instance.sqlDb);

instance.cx_jia_daoSession=instance.cx_jia_daoMaster.newSession();

}

这个代码主要是用于建立数据库和初始化一些变量,如初始化NoteDao的父类AbstractDao的变量和参数,

protected final SQLiteDatabase db;

protected final DaoConfig config;

protected IdentityScope identityScope;

protected IdentityScopeLong identityScopeLong;

protected TableStatements statements;

protected final AbstractDaoSession session;

protected final int pkOrdinal;

注意:

SQLiteDatabase db:我们建立的数据库对象;

DaoConfig config:用于保存数据访问对象Dao的基本数据;

TableStatements statements:用于生成操作数据表的SQL statements;

identityScope:greendao有一个缓存机制,即把用户插入,更改或查找的实体保存在内存中,当用户下一次查找时先从内存中查找

,如果不存在再从数据库中查找,当表的主键是数字类型的时候,identityScopeLong将不会空,并且指向identityScope。

在初始每个dao对象的DaoConfig的时候,判断主键是否是数字类型,

主键初始化:

如果主键是数字类型的话,initIdentityScope时identityScope 初始化IdentityScopeLong类型,

然后在数据操作对象的父类(AbstractDao)的构造方法中,将identityScopeLong 指向identityScope,之后我们只需要extends就可以了,如下图

 

然后,所有主键为数字类型dao对象获取内存中缓存对象的都会调用IdentityScopeLong中的get方法

 

所以,如果主键不是long类型的话就会报类型转换错误!

我们可以自己控制是否使用缓存功能,在DaoMaster中有两个初始化DaoSession的方法,我们可以使用第二个构造方法并传入type为IdentityScopeType.None,这样initIdentityScope方法就会包identityScope 赋为空值,即不使用缓存机制。

再次强调:在使用greendao缓存机制的情况下,如果数据表的主键是数字类型的话,一定要使用long类型,不然不会报类型转换错误。。大家可以去实践下

好进入正题:

1)插入对象(insert):

User user= new User("id","name");

getUserDao().insert(user);

底层代码如下:

 

首先判断数据库是否被当前线程锁住,如果是,绑定参数并执行插入,如果不是,则开启一个事务,然后绑定参数并执行插入。

其中,UserDao重写了父类AbstractDao的bindValues方法,进行相对应对象数据的绑定,

updateKeyAfterInsertAndAttach(entity, rowId, true)是为了更新自增主键的id,将实体放入缓存中。

(当然还有insertOrReplace ,他们直接的区别大家自己动手去研究,可以说从字面上理解就好了。深层次上的理解就得从sql语句了)

2)删除对象delete:

userDao.deleteByKey(id)

底层实现代码如下:

 

 

删除对象与插入对象相似,删除操作目前仅支持操作单一主键的表,assertSinglePk()是判断对象是否是单一主键,若不是则抛出错误。

往往我们要的是根据某个字段进行删除,如下

public void deleteMsgByUserName(String username) {

userDao.queryBuilder().where(UserDao.Properties.Username.eq(username)).buildDelete().executeDeleteWithoutDetachingEntities();

}

3)更改对象update:

userDao.update(user)

底层代码实现:

 

具体也是和添加,删除一样,先判断线程,然后再判断主键id。

当然我们也可以使用之前说的insertOrReplace,进行更新,底层代码和添加一样,区别在

 

 

Stringsql = SqlUtils.createSqlInsert("INSERT OR REPLACE INTO ",tablename,allColumns);

SQLiteStatement newInsertOrReplaceStatement =db.compileStatement(sql);

在编译时候到底是Inert 还是replace..

4)查找 

 

查找对象的实现实现是原理是传入多个限制条件,然后在底层代码中拼接sql查询语句进行查询,然后在转换成相对应的对象。查询的机制跟其他操作方式一样,如果有使用greendao的缓存机制,则先从缓存中获取,再从数据库获取,如果没有使用缓存机制,则直接从数据库中获取。

如果需要使用更复杂的查询方法的话,可以查看Property类和QueryBuilder的源码,greendao提供多种方式的拼接,可以组成日常开发中经常用到的查询语句。

需要一提的是greendao的懒加载功能。这个以后再说。

 

文/kecai(简书作者)
原文链接:http://www.jianshu.com/p/5681e183926d
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值