greenDAO(最新版本号V2.0.0的Readme)

========

greenDAO is a light & fast ORM solution for Android that maps objects to SQLite databases. Being highly optimized for Android, greenDAO offers great performance and consumes minimal memory.

1. 轻量、高速的ORM(Object Relation Mapping对象关系映射)解决方式,将实体对象映射到SQLite数据库中

2. Android开发中数据库操作的最佳方案

3. 提供高性能、消耗低内存

Home page, documentation, and support links: http://greendao-orm.com/

Features

greenDAO has a unique set of features:

  • Rock solid: greenDAO has been around since 2011 and is used by countless famous apps(2011年開始被用于非常多有名的应用开发中)
  • Super simple: concise and straight-forward API(简明好用的api)
  • Small: The library is <100K and it’s just plain Java jar (no CPU dependent native parts)(100kb大小。不依赖不同手机cpu型号native层,Android集成的java jar包就能够)
  • Fast: Probably the fastest ORM for Android, driven by intelligent code generation(android上最快的orm,自己主动生成代码,无需自己写繁琐的entity实体类,实体dao层处理类)
  • Safe and expressive query API: QueryBuilder uses property constants to avoid typos(简洁的api供查询)
  • V2.0.0 Powerful joins: query across entities and even chain joins for complex relations(眼下最新greendao已经有2.0版,添加了为比較复杂关系表,提供关联查询等)
  • V2.0.0 Flexible property types: use custom classes or enums to represent data in your entity

Add greenDAO to your project

greenDAO is available on Maven Central. Please ensure that you are using the latest versions by checking here and here

Gradle dependency for your Android app:

    compile 'de.greenrobot:greendao:2.0.0'

Gradle dependency for your Java generator project:

    compile 'de.greenrobot:greendao-generator:2.0.0'

(在Android Studio怎样引用greendao)

Features in Beta(说明还处于Beta版)

Those features are already here for you to try out. Note: Documentation and test coverage may be lacking, and the API may change in the future.

Asynchronous API(异步操作api)

  • New AsyncSession (acquired from DaoSession.startAsyncSession()) provides most operations for DAOs, Queries, and transactions in a asynchronously variant
  • AsyncOperations are processed in order by a background thread
  • waitForCompletion methods for AsyncSession and AsyncOperations
  • AsyncOperationListener for asynchronous callback when operations complete
  • Asynchronous operations can be merged in single transactions (details follow)
  • Added raw SQL queries returning a Query object (LazyList support etc.)

More Open Source by greenrobot

EventBus is a central publish/subscribe bus for Android with optional delivery threads, priorities, and sticky events. A great tool to decouple components (e.g. Activities, Fragments, logic components) from each other.(greenrobot团队的还有一有名开源项目)

greenrobot-common is a set of utility classes and hash functions for Android & Java projects.

Follow us on Google+ to stay up to date.

——————————-华丽的切割线———————————-

For the same given entity, greenDAO inserts and updates entities over 2 times faster, and loads entities 4.5 times faster for loading entities than ORMLite. For typical applications the loading speed is the most important.

(比起ORMLite快,同样的数据,更新是它的两倍。查询是它的4.5倍)

greenDAO 使用「Code generation」的方式

DAO CODE GENERATION PROJECT



这是其核心概念:为了在我们的 Android 工程中使用 greenDAO ,我们须要另建一个纯 Java Project,用于自己主动生成后继 Android 工程中须要使用到的 Bean、DAO、DaoMaster、DaoSession 等类。

CORE CLASSES & MODELLING ENTITIES

从https://github.com/greenrobot/greenDAO上下载整个完整的项目,然后导入到Android Studio中去,修复參数配置,终于在IDE中完整的项目结构文件夹例如以下:

Entity


    Entity simple = schema.addEntity("SimpleEntity");
simple.addIdProperty();
simple.addBooleanProperty("simpleBoolean");
simple.addByteProperty("simpleByte");
simple.addShortProperty("simpleShort");
simple.addIntProperty("simpleInt");
simple.addLongProperty("simpleLong");
simple.addFloatProperty("simpleFloat");
simple.addDoubleProperty("simpleDouble");
simple.addStringProperty("simpleString");
simple.addByteArrayProperty("simpleByteArray"); //生成一个ContentProvider内容提供器,供其它程序訪问数据
simple.addContentProvider().readOnly();

QueryBuilder


查询就是返回符合一定条件的实体。

可使用原始的SQL语句运行查询;或是更好的方式,使用greenDAO中QueryBuilder的API。查询支持懒载入。当操作较大的结果集时。便可节约内存、提高性能。

举例:查询全部名为“Joe”的用户。且按姓排序。

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

嵌套条件的样例:获取名为“Joe”出生在1970年10月份或1970年之后的用户。

假如用户的生日分成年月日三个字段,这样便可换一种方式来表示上面的查询:名字是“Joe” AND (生日年份大于但不包含1970 OR(生日年份是1970 AND 月份大于等于10))。

QueryBuilder qb = userDao.queryBuilder();
qb.where(Properties.FirstName.eq("Joe"),
qb.or(Properties.YearOfBirth.gt(1970),
qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));
List youngJoes = qb.list();
**(注意上面的括号。为了引出ge推断条件大于等于)

GreenDAO的Properties字段属性查询条件全部定义在了一个de.greenrobot.dao.Property类里面,详情请參照该类里面方法说明。

QueryBuilder的查询推断全部定义在一个de.greenrobot.dao.query.QueryBuilder类里面,详情请參照该类里面方法说明。

Query和LazyList

Query类代表着一个查询,可被运行多次。但使用QueryBuilder的方法之中的一个(如list())获取一个结果时。QueryBuilder内部就是使用Query类。假设要多次运行同样的请求,可调用QueryBulder的build()方法创建一个查询而非运行它。

greenDAO同一时候支持获取单个结果(0或者1个结果)和结果列表。

若期待获取一个结果能够调用Query(或QueryBulder)的unique(),这将返回一个结果或匹配不到返回null。若不同意返回nul,可调用uniqueOrThrow(),它将保证返回一个非null实体(否则会抛出一个DaoException)。

若期待返回多个结果,能够调用以下的list…方法:

list()       全部实体载入内存,以ArrayList形式返回,使用最简单。

listLazy()       实体按需载入到内存。当列表中的当中一个元素第一次被訪问。它会被载入并缓存备将来使用。

使用完必须关闭。

listLazyUncached()       一个“虚拟”的实体列表:不论什么訪问列表中的元素都会从数据库中读取。使用完必须关闭。

listIterator()       可迭代訪问结果集,按需载入数据,数据不缓存。使用完必须关闭。

方法listLazy,listLazyUncached和 listIterator需使用greenDAO的LazyList类。LazyList持有一个数据库游标,可按需载入数据。

这也是为什么必须确保关闭懒载入列表和迭代器(通常使用try/finally包裹)。listLazy()的懒载入列表和listIterator()懒载入迭代器,在全部元素被訪为或遍历后自己主动关闭游标。可是。还是必须调用close()方法。防止list的运行过早结束。

多次运行查询

通过QueryBuilder创建一个Query,Query对象能够在一次查询结束后又一次使用。

相比创建新的Query对象,这样更加高效。假设查询參数没有改变,可再次调用list/unique方法。假设參数改变。则必须调用setParameter方法改动对应的參数。參数的索引地址从0開始。而索引为參数加入到QueryBuilder的顺序。

以下的样例使用一个查询对象,获取以“Joe”为名,出生于1970年的用户:

Query query = userDao.queryBuilder().where(
Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970))
.build();
List joesOf1970 = query.list();

使用该查询对象,可搜索“Marias”生于1977年:

query.setParameter(0, "Maria");
query.setParameter(1, 1977);
List mariasOf1977 = query.list();

多线程运行查询

多线程中使用查询。必须调用Query的forCurrentThread()获取当前线程的查询实例。

从greenDAO1.3開始。Query对象实例绑定到创建它的线程。

这样便可安全的设置Query对象的參数,不受其它线程影响。假设其它线程试图设置參数或运行查询,将抛出异常。这样便无需使用同步语句。

实际上我们应该避免加锁。由于在并发处理使用了同样的查询对象。easy导致死锁。

为全然避免潜在的死锁,greenDAO1.3引入方法forCurentThread(),返回一个本地线程的Query对象,能够被当前线程安全使用。每次forCurrentThread()方法被调用,全部參数将被设置成该查询被其builder创建时的參数。

原始查询

有两种方法运行原始SQL语句,获取实体结果集。

最好的方式是使用QueryBuilder和WhereCondition.StringCondition。可传入不论什么SQL片段到WHERE字句。例如以下:

Query query = userDao.queryBuilder().where(
new StringCondition("_ID IN " +
"(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();

当QueryBuilder的功能未能符合需求时,可使用queryRaw或queryRawCreate方法。

你可传入一个原始语句,它会被加入到SELECT和实体字段后。

用这样的方式能够编写不论什么WHERE和ORDER BY字句去查询须要的实体集。实体表能够使用别名“T”来引用。

以下的样例使用联合查询检索所在组为“admin”的全部用。

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

注意:可用生成的常量表示表名和字段名。这是推荐的做法。避免编写错误。在一个实体的DAO中。TABLENAME表示数据库的表名。其内部类Properties则有全部属性的常量。

删除实体

删除实体的基类是de.greenrobot.dao.AbstractDao,里面提供了删除的api

public void deleteAll() {
// String sql = SqlUtils.createSqlDelete(config.tablename, null);
// db.execSQL(sql); db.execSQL("DELETE FROM '" + config.tablename + "'");
if (identityScope != null) {
identityScope.clear();
}
} /** Deletes the given entity from the database. Currently, only single value PK entities are supported. */
public void delete(T entity) {
assertSinglePk();
K key = getKeyVerified(entity);
deleteByKey(key);
} /** Deletes an entity with the given PK from the database. Currently, only single value PK entities are supported. */
public void deleteByKey(K key) {
……
}

这个类还提供了loadAll和insert方法

支持事务

SQLite 数据库是支持事务的,事务的特性能够保证让某一系列的操 作要么全部完毕,要么一个都不会完毕。

GreenDAO也封装了SQLite的事务属性,如de.greenrobot.dao.AbstractDao类里(详细怎样做SQLite事务的封装请參照源代码):

/**
* Inserts the given entities in the database using a transaction.
*
* @param entities
* The entities to insert.
*/
public void insertInTx(Iterable<T> entities) {
insertInTx(entities, isEntityUpdateable());
}

检測查询

假设查询结果没有返回你期待的,有两个静态标识可开启QueryBuilder的SQL和參数的日志输出:

QueryBuilder.LOG_SQL = true;
QueryBuilder.LOG_VALUES = true;

这样会输出SQL命令和调用相关build方法时传入的參数。

个人感悟

只是这个框架的本质是对sqlite数据库api的封装。提供了更简洁的api调用。相对使用android原生sqlite的优势有:

1、对于ORM关系型数据库,sqlite须要自己写sql语句来组织数据之间的关系,greendao提供了更加便捷的api为我们攻克了。

2、实现了数据库查询list集合的缓存机制,这是sqlite所没有的。

3、攻克了多线程查询中遇到的各种问题,避免了sqlite的加锁查询。

4、框架实现。让代码更加规范更加简洁。

结语

GreenDAO框架给我们提供了在Android平台上非常好的ORM框架设计思路。是一个非常值的学习的开源项目。

greenDAO学习分享总结的更多相关文章

  1. ElasticSearch 5学习(7)——分布式集群学习分享2

    前面主要学习了ElasticSearch分布式集群的存储过程中集群.节点和分片的知识(ElasticSearch 5学习(6)--分布式集群学习分享1),下面主要分享应对故障的一些实践. 应对故障 前 ...

  2. ElasticSearch 5学习(6)——分布式集群学习分享1

    在使用中我们把文档存入ElasticSearch,但是如果能够了解ElasticSearch内部是如何存储的,将会对我们学习ElasticSearch有很清晰的认识.本文中的所使用的ElasticSe ...

  3. MySQL学习分享--Thread pool实现

    基于<MySQL学习分享--Thread pool>对Thread pool架构设计的详细了解,本文主要对Thread pool的实现进行分析,并根据Mariadb和Percona提供的开 ...

  4. JavaScript Shell学习分享

    目录 JavaScript Shell学习分享 简介 安装 使用原因 小结 JavaScript Shell学习分享 简介 JavaScript Shell是由Mozilla提供的综合JavaScri ...

  5. python 学习分享-paramiko模块

    paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Solaris, BS ...

  6. 有关JSOUP学习分享(一)

    其实现在用JSOUP爬虫的也不多了,但是由于最近换公司,做数据爬虫需要用到,就看了下,感觉还是挺好用的,原理什么的感觉和weblogic也差不到哪里去,废话少说,这里就简单的分享下最近接触的干货. J ...

  7. Swagger框架学习分享

    Swagger框架学习分享 转至元数据结尾 Created and last modified by 刘新宇 大约1分钟曾经 pageId=162045803#page-metadata-start& ...

  8. Flink 从0到1学习—— 分享四本 Flink 国外的书和二十多篇 Paper 论文

    前言 之前也分享了不少自己的文章,但是对于 Flink 来说,还是有不少新入门的朋友,这里给大家分享点 Flink 相关的资料(国外数据 pdf 和流处理相关的 Paper),期望可以帮你更好的理解 ...

  9. python paramiko模块学习分享

    python paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Sola ...

随机推荐

  1. nyoj 1282 部分和问题

    部分和问题(入门题) 时间限制:1000 ms  |  内存限制:65535 KB 难度:0   描述 给你n个数(a1,a2,a3.......an) ,是否存在某一些数字加起来等于k,有就输出 & ...

  2. Canvas与Image互相转换示例以及利用该技术实现微信长按自动识别二维码功能

    现在扫描二维码已经很普遍,微信扫一扫即可,但是如果二维码是在自己的手机上呢?那就要用到微信里的一个功能了,手指长按二维码,会弹出自动识别的选项,点确定就可以看到二维码的内容了.那么怎么通过前端实现这个 ...

  3. hihoCoder #1783 又一个重复计数

    题目大意 给定一个长度为 $n$ 的字符串 $S$,定义函数 $f(S)$ 表示 $S$ 的不同回文子串的个数.对于 $1\le l \le r \le n$,定义 $S[l,r]$ 为字符串 $S$ ...

  4. JAVA简易的注册会员系统

    public class Login { public static void main(String[] args) { System.out.println("*****欢迎进入注册系统 ...

  5. Activity启动创建 (AcitivtyManageService,ActivityThread,Activity)

    ActivityThead,ActivityManagerService,Activity  <<Android内核剖析>>中有一章节专门介绍 Activity框架和管理结构A ...

  6. POJ2478 Farey Sequence

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15023   Accepted: 5962 Description The ...

  7. 浏览器的 16ms 渲染帧

    标签 归档 关于arttle Land 浏览器的 16ms 渲染帧 DOM JavaScript 异步 性能 重绘 由于现在广泛使用的屏幕都有固定的刷新率(比如最新的一般在 60Hz), 在两次硬件刷 ...

  8. Codeforces 916E Jamie and Tree (换根讨论)

    题目链接  Jamie and Tree 题意  给定一棵树,现在有下列操作: $1$.把当前的根换成$v$:$2$.找到最小的同时包含$u$和$v$的子树,然后把这棵子树里面的所有点的值加$x$: ...

  9. Springboot如何优雅的解决ajax+自定义headers的跨域请求

    1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发 ...

  10. Fresco,Facbook强大的图片加载框架

    项目git地址:https://github.com/facebook/fresco Fresco是 facebook推出的一款强大的图片加载的框架:主要有Image Pipeline和Drawees ...