• 前言
  • 应用层原理简介
  • 1 编译后自动注入的文件有哪些
  • 2 获取一个Dao对象的过程
  • 21 代码示例
  • 22 分段解释创建过程
  • 关于注解
  • 基本应用
  • 1 创建一个Bean
  • 2 获取Dao实例
  • 21 获取DaoSession实例
  • 22 获取Dao实例
  • 23 Dao操作增删改查示例
  • 结语

1. 前言

  • 主要介绍GreenDao的基本应用。
  • 本文资料来源网络公开资源,并根据个人实践见解纯手打整理,如有错误请随时指出。
  • 本文主要用于个人积累及分享,文中可能引用其他技术大牛文章(仅引用链接不转载),如有侵权请告知必妥善处理。

2. 应用层原理简介

  • 如果这部分看起来感觉抽象难懂,可以先看之后的实操部分,操作一遍之后再回头看,更容易理解此部分。

2.1. 编译后自动注入的文件有哪些

GreenDao是什么我想已无需多解释,关键是了解它在一个事务发起时是怎样去执行一系列代码的。 首先需要了解编译后,GreenDao注入的java文件,主要有哪些,功能是什么。

  • 在《GreenDao配置流程》中,schema配置了”daoPackage ‘xx.xxx.xxxxx.greendao.dao’”,当rebuild后,daoPackage所指定的包路径下,我们可以找到自动生成的文件有:
  • DaoMaster.java
  • 入口类,在任何情况下操作数据库的入口。
  • 包含注册XxxxBeanDao类,创建DaoSession实例,操作DatabaseOpenHelper相关的创建表、删除表、更新数据库等操作
  • 创建映射关系
  • DaoSession.java
  • 创建所有Bean类对应的Dao类的实例,完成映射关系
  • 每个Bean类对应的Dao类
  • 数据库操作类,继承自抽象类AbstractDao

2.2. 获取一个Dao对象的过程

2.2.1. 代码示例:

DaoSession daoSession = new DaoMaster(new DaoMaster.DevOpenHelper(context, DATA_BASE_NAME).getWritableDb()).newSession();
daoSession.getXxxxBeanDao();

2.2.2. 分段解释创建过程

  • new DaoMaster(…);
  • DaoMaster类的构造方法中,传入的Database实例使用DaoMaster中DevOpenHelper创建,自定义DATA_BASE_NAME
  • DaoMaster类的构造方法中,进入registerDaoClass(…)方法,可以看到这一操作实际上是将XxxxBeanDao.class加入其抽象父类AbstractDaoMaster的一个map:daoConfigMap中,以把DaoConfig和XxxxBeanDao.class绑定,如下图:

  • 进入DaoConfig类,可以看到,构造方法中代码实际上是一个创建反射机制的过程,这为每个Dao准备好TableName、Property、Pk等一系列参数。每个Dao都将创建一个对应的DaoConfig与之绑定,具体代码不再截图,此类比较简单,但非常重要,后面也会提到。
  • newSession();
  • 接续上面的内容,回到DaoMaster类,看到daoConfigMap实际是用来创建DaoSession实例的参数,如下图:

  • 创建DaoSession实例时,进入DaoSession类的方法可以看到,调用了daoConfigMap的clone()方法得到所有对应Dao文件的daoConfig,并对其创建缓存入口,这个缓存创建的方法是DaoConfig类中initIdentityScope(IdentityScopeType type)
  • 在DaoSession创建中,将创建所有Bean类对应的Dao类的实例,并将XxxxBean.class和对应的Dao类绑定,到此为止GreenDao框架内部基本已完成了对象关系映射处理
  • 此时可以 2.2.1. 的示例代码,可以轻松获得Bean类的操作类XxxxBeanDao的实例。

3. 关于注解

注解的说明,参考官方文档即可,很详细,比较理论的内容貌似没有在这里复述的必要,请参看如下链接: http://greenrobot.org/greendao/documentation/modelling-entities/

4. 基本应用

将主要通过示例学习 参考官方api:http://greenrobot.org/greendao/documentation/javadoc/

4.1. 创建一个Bean

参看如下PeopleBean.java代码和注释

//注意:准备做数据库存储的Bean,必须添加@Entity注解
@Entity
public class PeopleBean {
    @Id
    //此处有坑,务必注意
    //注意:必须使用包装类型Long,而非基本类型long
    private Long id;
    @NotNull
    private String name;
    private int age;
    private String province;
    private boolean isMale;
    @Unique
    private String idCard;

    //注意:get、set方法,无需自己生成,当此类创建完成后,rebuild项目,将自动生成

    //注意:toString是需要自己创建生成的
    @Override
    public String toString() {
        return "PeopleBean{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", province='" + province + '\'' +
                ", isMale=" + isMale +
                ", idCard='" + idCard + '\'' +
                '}';
    }
}

4.2. 获取Dao实例

前提:rebuild项目

4.2.1. 获取DaoSession实例

  • 需要注意的是,DaoSession实例包含该项目中所有已被@Entity注解的Bean所创建的Dao类实例,故DaoSession实例最好为单例模式,并加锁
  • 或者,将DaoSession创建在该工程的Application类中,也可以形成事实上的单例

这里示例代码展示创建一个单例的工具类,用来获取DaoSession实例:

public class GreenDaoUtil {
    private static DaoSession daoSession;
    private final static String DATA_BASE_NAME = "test_01.db";

    public synchronized static DaoSession getDaoSession(Context context) {
        if (daoSession == null) {
            daoSession = new DaoMaster(new DaoMaster.DevOpenHelper(context, DATA_BASE_NAME).getWritableDb()).newSession();
        }
        return daoSession;
    }

}

4.2.2. 获取Dao实例

GreenDaoUtil.getDaoSession(activity).getPeopleBeanDao();

4.2.3. Dao操作增删改查示例

复杂应用不一一示例,后面系列文章将逐渐体现

GreenDaoUtil.getDaoSession(activity).getPeopleBeanDao().insert(peopleBean);

GreenDaoUtil.getDaoSession(activity).getPeopleBeanDao().deleteByKey(peopleBean.getId());

GreenDaoUtil.getDaoSession(activity).getPeopleBeanDao().update(peopleBean);

//全部
List<PeopleBean> peopleBeanList = GreenDaoUtil.getDaoSession(activity).getPeopleBeanDao()
                        .queryBuilder()
                        .list();

//条件查
List<PeopleBean> peopleBeanList = GreenDaoUtil.getDaoSession(activity).getPeopleBeanDao()
                        .queryBuilder()
                        .where(PeopleBeanDao.Properties.Age.gt(30), PeopleBeanDao.Properties.IsMale.eq(true))
                        .list();

注意: 查询方法返回的 List,从源码上看,永不为null,可以省略对其null判断,直接foreach使用

5. 结语

这一部分基本没有什么坑,比较简单,还是总结下关键点,如下:

  • 对于应用层的一些较浅层源码,最好还是熟悉下,便于以后的应用
  • 对注解的需要熟悉
  • 主键Id,必须包装类Long型,避免各种坑
  • DaoSession实例需要单例
  • 当Bean变量被改变(或任何涉及数据库的改变),rebuild后数据库对应的表结构也会随之改变,这时必须schema配置必须将schemaVersion +1