greenDAO学习分享总结
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学习分享总结的更多相关文章
- ElasticSearch 5学习(7)——分布式集群学习分享2
前面主要学习了ElasticSearch分布式集群的存储过程中集群.节点和分片的知识(ElasticSearch 5学习(6)--分布式集群学习分享1),下面主要分享应对故障的一些实践. 应对故障 前 ...
- ElasticSearch 5学习(6)——分布式集群学习分享1
在使用中我们把文档存入ElasticSearch,但是如果能够了解ElasticSearch内部是如何存储的,将会对我们学习ElasticSearch有很清晰的认识.本文中的所使用的ElasticSe ...
- MySQL学习分享--Thread pool实现
基于<MySQL学习分享--Thread pool>对Thread pool架构设计的详细了解,本文主要对Thread pool的实现进行分析,并根据Mariadb和Percona提供的开 ...
- JavaScript Shell学习分享
目录 JavaScript Shell学习分享 简介 安装 使用原因 小结 JavaScript Shell学习分享 简介 JavaScript Shell是由Mozilla提供的综合JavaScri ...
- python 学习分享-paramiko模块
paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Solaris, BS ...
- 有关JSOUP学习分享(一)
其实现在用JSOUP爬虫的也不多了,但是由于最近换公司,做数据爬虫需要用到,就看了下,感觉还是挺好用的,原理什么的感觉和weblogic也差不到哪里去,废话少说,这里就简单的分享下最近接触的干货. J ...
- Swagger框架学习分享
Swagger框架学习分享 转至元数据结尾 Created and last modified by 刘新宇 大约1分钟曾经 pageId=162045803#page-metadata-start& ...
- Flink 从0到1学习—— 分享四本 Flink 国外的书和二十多篇 Paper 论文
前言 之前也分享了不少自己的文章,但是对于 Flink 来说,还是有不少新入门的朋友,这里给大家分享点 Flink 相关的资料(国外数据 pdf 和流处理相关的 Paper),期望可以帮你更好的理解 ...
- python paramiko模块学习分享
python paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Sola ...
随机推荐
- BZOJ 1192:[HNOI2006]鬼谷子的钱袋(数学)
鬼谷子的钱袋Description鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政.有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的拍卖行(聚宝商行)将要举行一场拍卖会 ...
- [HNOI2007][bzoj1187] 神奇游乐园 [插头dp]
题面: 传送门 给定一个四联通棋盘图,每个格子有权值,求一条总权值最大的回路 思路: 插头dp基础教程 棋盘? 回路? n,m<=10? 当然是插头dp啦~\(≧▽≦)/~ 然后发现这道题并不是 ...
- Spring Boot是什么
Spring Boot是什么 我们知道,从 2002 年开始,Spring 一直在飞速的发展,如今已经成为了在Java EE(Java Enterprise Edition)开发中真正意义上的标准,但 ...
- BZOJ2194 快速傅立叶之二 【fft】
题目 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非负整数. 输入格式 ...
- HDU 3792 素数打表
Description If we define dn as: dn = pn+1-pn, where pi is the i-th prime. It is easy to see that d1 ...
- ext2 与 ext3
http://linux.vbird.org/linux_basic/1010appendix_B.php https://baike.baidu.com/item/Ext2/822106?fr=al ...
- cf 613E - Puzzle Lover
Description 一个\(2*n\)的方格矩阵,每个格子里有一个字符 给定一个长度为\(m\)的字符串\(s\) 求在方格矩阵中,有多少种走法能走出字符串\(s\) 一种合法的走法定义为:从任意 ...
- configurationmanager.getsection usage
public static void CreateAppSettings() { // Get the application configuration file. System.Configura ...
- Docker(七):仓库
登录 可以通过执行docker login命令来输入用户名和密码,密码和邮箱来完成注册和登录.注册成功之后,本地用户目录的.dockerfig中将保存用户的认证信息. 使用$sudo docker s ...
- Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤
http://blog.csdn.net/vagrxie/article/details/4602961 Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤 wri ...