史上最高效的ORM方案——GreenDao3.0详解
2016-12-04 16:02 阅读(236)

1. 什么是greenDao

弄明白greenDao之前我们应该先了解什么是ORM(Object Relation Mapping 即 对象关系映射),说白了就是将面向对象编程语言里的对象与数据库关联起来的一种技术,而greenDao就是实现这种技术之一,所以说greenDao其实就是一种将java object 与SQLite Database关联起来的桥梁,它们之间的关系 如下图所示;


greenDao ,SQLite Database与Java Object对象之间的关系

2. 为什么要使用greenDao

greenDao可以说是当今最流行,最高效而且还在迭代的关系型数据库。而且greenDao3.0还支持RxJava操作,greenDao如此受欢迎离不开以下几点:


几种常用数据库比较

3. 怎样使用greenDao

3.1 入门

3.1.1  配置GreenDao

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
     classpath 'org.greenrobot:greendao-gradle-plugin:3.2.0'//greenDao生产代码插件
    }
apply plugin: 'org.greenrobot.greendao'//greendao插件
dependencies {
      compile 'org.greenrobot:greendao:3.2.0'

配置数据库信息

greendao {
        //数据库schema版本,也可以理解为数据库版本号
        schemaVersion 2
        //设置DaoMaster 、DaoSession、Dao包名
        daoPackage 'com.qhn.bhne.footprinting.db'
        //设置DaoMaster 、DaoSession、Dao目录
        targetGenDir 'src/main/java'
        //设置生成单元测试目录
//    targetGenDirTest
        //设置自动生成单元测试用例
//    generateTests
    }

到这里数据库基本配置已经完成,接下来让我们一起来了解下greenDao的核心类该怎样使用吧。
3.1.2  核心类介绍


greenDao核心类构成

3.1.3 构建Model类

Molde类需要用java类来定义并且可以通过GreenDao中的注释来表明Model中的每个属性在数据库的中该如何定义;定义model类后点击Make project选项GreenDao就会自动生成DaoMaster,DaoSession,和DAOS类,生成的代码将会保存在预先在budle gradle中设置的位置

@Entity
public class User { 
        @Id 
        private Long id;  private String name; 
        @Transient 
        private int tempUsageCount; // 没有存入数据库中
 }


@Entity

//如果该实体属于多个表单,可以使用该参数; 
schema = "myschema",  
// 该实体属于激活状态,激活状态的实体有更新,删除,刷新方法; 
active = true,  
// 给这个表指定一个名字,默认情况下是名字是类名 
nameInDb = "AWESOME_USERS",
 // 可以给多个属性定义索引和其他属性.
 indexes = { @Index(value = "name DESC", unique = true) },  
//是否使用GreenDao创建该表.
 createInDb = false,   
// 是否所有的属性构造器都应该被生成,无参构造器总是被要求
 generateConstructors = true,  
// 如果该类中没有set get方法是否自动生成 
generateGettersSetters = true

基本注释属性

Error:Execution failed for task ':app:greendao'.> Constructor (see 
ExampleEntity:21) has been changed after generation.Please either mark 
it with @Keep annotation instead of @Generated to keep it untouched,or
use @Generated (without hash) to allow to replace it.

这是因为在通过javabean对象自动生成entities类时,greenDao会增加实体类代码,@Generated注释部分与GreenDao增加的代码相关,胡乱修改@Generated代码,就会导致entities部分属性与javabean不匹配导致报错;有俩种方法可以避免这种错误

@Entity
public class User { 
      @Id(autoincrement = true)
       private Long id;  
      @Property(nameInDb = "USERNAME") 
       private String name;  
      @NotNull 
      private int repos;  
      @Transient 
      private int tempUsageCount; 
 ...}
@Id
private Long id; 
@Index(unique = true)
private String key;

索引属性
使用@Index 可以将一个属性变为数据库索引;其有俩个参数

@Entity
public class User { 
@Id 
private Long id;
 @Index(unique = true)
 private String name;
}

核心代码初始化
创建数据库过程

// 下面代码仅仅需要执行一次,一般会放在application
helper = new DaoMaster.DevOpenHelper(this, "notes-db", null);
db = helper.getWritableDatabase();daoMaster = new DaoMaster(db);daoSession = daoMaster.newSession();
// 在activity或者fragment中获取Dao对象
noteDao = daoSession.getNoteDao()


List joes = userDao.queryBuilder() 
.where(Properties.FirstName.eq("Joe")) 
.orderAsc(Properties.LastName) .list();

嵌套挑去查询语句:查询一个出生在1970年10月或者以后的"joe"用户

QueryBuilder qb = userDao.queryBuilder();
qb.where(Properties.FirstName.eq("Joe"),//第一个约束条件姓乔
qb.or(Properties.YearOfBirth.gt(1970),//或者出生日期大于1970年
qb.and(Properties.YearOfBirth.eq(1970), 
Properties.MonthOfBirth.ge(10))//并且在1970年出生 但是月份大于
10月的));
List youngJoes = qb.list();

后面三个方法是LazyList类中的方法,LazyList为了执行不同的缓存策略其内部持有数据库的cursor对象;一般情况下这三个方法执行完毕后会自动关闭cursor;但是防止在还没有执行完查询结果时,对象被终结cursor还是无法被关闭的情况发生,需要手动关闭close();

// fetch users with Joe as a first name born in 1970Query 
query = userDao.queryBuilder().where( 
Properties.FirstName.eq("Joe"), 
Properties.YearOfBirth.eq(1970)).build();List joesOf1970 = 
query.list(); // using the same Query object, we can change the 
parameters// to search for Marias born in 1977 
later:query.setParameter(0, "Maria");query.setParameter(1, 
1977);List mariasOf1977 = query.list();
Query query = userDao.queryBuilder().where( new 
StringCondition("_ID IN " + "(SELECT USER_ID FROM 
USER_MESSAGE WHERE READ_FLAG = 0)")).build();

备选方法 :
使用queryRaw 或者queryRawCreate:

Query query = userDao.queryRawCreate( ", GROUP G WHERE 
G.NAME=? AND T.GROUP_ID=G._ID", "admin");

好了这一期的GreenDao的介绍到这里就结束了,本期主要讲解了greenDao的基本概念与基本操作,下一期我会介绍GreenDao的高级操作:session缓存多表查询多表关联自定义参数类型



作者:D丶C