第五篇 查询

查询会返回符合某些特定标准的实体。你可以使用原始的SQL定制查询语句,或者更好的方式:使用GreenDao的QueryBuilder API。该查询也支持lazy-loading的结果集。这样在操作大量结果集的时候可以节省内存和性能。

QueryBuilder

QueryBuilder可以帮助你构建自定义的查询语句,而不使用SQL的情况。并不是每个人都喜欢书写SQL语句,当然很容易就会出一些错,这些错误只有在运行的时候才会被发现。而QueryBuilder很容易使用,节省了你书写SQL语句的时间。当然,由于语法的检验是在编译时才执行,所以在查询语句中发现bug是很困难的。
QueryBuilder的编译时间会检验属性的引用,这样能够在greenDao后面,通过代码生成的方法发现bug。
比如:查找所有以“Joe”为first name 的用户,并以last name排序:

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

嵌套情况

获取用户名字为“Joe”并且在1970年9月之后出生的用户
这里要说明下:user 的birthday对于year,month,和day是一个分离的属性。我们可以以一种更正常的方式表达这种条件:
First name is “Joe” AND (year of birth is greater than 1970 OR (year of birth is 1970 AND month of birth is equal to or greater than 10 (October).

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();

Query 和 LazyList

Query类代表一个可以多次执行的查询。当你使用QueryBuilder之一的方法去获取结果的时候,QueryBuilder内部使用了Query 类。
如果你想运行更多相同的查询,你应该调用build()在QueryBuilder上,去创建Query,而不是执行它。
greenDao支持唯一的结果和结果列表。如果你想得到一个唯一的结果,可以调用Query或者QueryBuilder的unique()方法,这样在没有匹配条件的时候会返回一个唯一的结果,而不是null。如果你希望禁止用例中返回null,可以调用uniqueOrThrow(),该方法会保证返回一个非null的实体。否则就会抛出一个DaoException。

如果你期望一次性返回多个实体,可以使用以下方法:
list():所有的实体被加载到内存中。该结果通常是一个没有magic involved的ArrayList。使用起来最简单。
listLazy():实体按照需求加载进入内存。一旦列表中的一个元素被第一次访问,它将被加载同时缓存以便以后使用。必须close。
ListLasyUncached(): 一个“虚拟”的实体列表:任何对列表元素的访问都会导致从数据库中加载,必须close。
listIterator(): 遍历通过需要的时候加载(lazily)获得的结果,数据没有缓存,必须close。
listLazy, listLazyUncached 和 listIterator类使用了greenDao的LazyList类。为了根据需求加载数据,它持有了一个数据库cursor的引用。
这是做是为了确保关闭 lazy list和iterators(通常在try/finally 代码块中)。
一旦有的元素被访问或者遍历过,来自lsitLazy()的cache lazy list和来自listIterator()方法的lazy iterator将会自动关闭cursor。
然而,如果list的处理过早的完成了,你应该调用 close()手动关闭。

多次执行查询

一旦你使用QueryBuilder构建了一个query,该query对象以后可以被重复使用。这种方式比总是重复创建query对象要高效。
如果query的参数没有变更,你只需要再次调用list/unique方法即可。如果有参数变更,你就需要调用setParameter方法处理每一个变更的参数。
现在,个别参数由基于零的参数索引寻址。该下标基于你传递到querybuilder的参数。

使用query对象获取出生在1970年 并且 first name 为 joe 的用户:

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

使用query对象,可以查询

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

在多个线程中执行查询

如果你在多线程中使用了查询,你必须调用query的 forCurrentThread()为当前的线程获得一个query实例。从greenDAO 1.3开始,
query的实例化被绑定到了那些创建query的线程身上。这样做保证了query对象设置参数时的安全性,避免其他线程的干扰。如果其他线程
试着在query对象上设置参数或者执行查询绑定到了其它线程,将会抛出异常。这样一来,你就不需要一个同步语句了。
事实上你应该避免使用lock,因为如果在并发的事务中使用了同一个query对象,可能会导致死锁。
为了完全避免那些潜在的死锁问题,greenDAO 1.3 引入了forCurrentThread方法,它会返回一个query对象的thread—local实例,该实例
在当前的线程中使用是安全的。当每一次调用 forCueerntThread()的时候,该参数会在builder构建query的时候,设置到初始化参数上。

原始的查询

这里有两种方式执行原始的SQL去获取实体。较好的一种方式是使用QueryBuilder 和 WhereCondition.StringCondition。
使用这个方法,你可以为 query builder 的 WHERE 子句传递任何SQL片段。
下面是一个笨拙的例子展示如果使用这种方式进行一个替代联合查询的子查询。

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

该示例中query Builder没有提供你需要的特性,你可以回到原始的queryRaw或者queryRawCreate方法。它们允许你传递原始的SQL字符串,这些字符串会被添加到SELECT 和实体列后面。这种方式,你可以拥有一个 WHERE 和 ORDER BY 语句查询实体。这种实体表可以通过别名“T”引用。

下面的例子展示了如何创建一个query:使用联合获取名为“admin”的group的users

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

提示

你可以通过生成的常量引用表或者列名。这样建议是为了避免错别字,因为编译器会检验这些名字。在任何实体的DAO,你可以发现 TABLENAME 持有着数据库的名字和一个内部类“Properties”.它的所有属性都是常量。

删除查询

批量删除不删除单独的实体,但所有的实体要匹配一些准则。为了执行批量删除,创建一个QueryBuilder,调用它的buildDelete方法,它会返回一个DeleteQuery。

这部分的API可能会在以后有所变化,比如添加一些更加便利的方法。记住,批量删除现在不会影响到identity scope中的实体。在它们被通过ID访问之前(load 方法)

如果它们被缓存了,你可以激活那些将要被删除的实体。如果导致了一些使用的问题。你可以考虑清除identity scope。

查询故障处理

如果你的query没有返回期望的结果,这里有两个静态的flag,可以开启QueryBuilder身上的SQL和参数的log。

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

它们会在任何build方法调用的时候打印出SQL命令和传入的值。这样你可以对你的期望值进行对比,或许也能够帮助你复制SQL语句到某些

SQLite 数据库的查看器中,执行并获取结果,以便进行比较。

本文转自:http://blog.csdn.net/xushuaic/article/details/24496191

GreenDao官方文档翻译(下)的更多相关文章

  1. GreenDao官方文档翻译(上)

    笔记摘要: 上一篇博客简单介绍了SQLite和GreenDao的比较,后来说要详细介绍下GreenDao的使用,这里就贴出本人自己根据官网的文档进行翻译的文章,这里将所有的文档分成上下两部分翻译,只为 ...

  2. Alljoyn瘦客户端库介绍(官方文档翻译 下)

    由于其他事情耽误,这个翻译现在才完成.接上篇—— 4 瘦客户端核心库架构 由于AllJoyn瘦客户端核心库(AJTCL)必须运行在那些功耗受限.计算能力有限.资源紧缺的设备上,因此它无法像运行在通用型 ...

  3. Data Binding Guide——google官方文档翻译(下)

    这篇博客是Data Binding Guide官网文档翻译的下篇.假设没看过前半部分翻译的能够先看Data Binding Guide--google官方文档翻译(上)  一,数据对象 不论什么不含业 ...

  4. Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)中一些知识点

    Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Flume官方文档翻译--Flume 1.7.0 User Guide (unr ...

  5. Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)(二)

    Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Logging raw data(记录原始数据) Logging the raw ...

  6. Aircrack-ng官方文档翻译[中英对照]---Airmon-ng

    Aircrack-ng官方文档翻译---Airmon-ng Description[简介] This script can be used to enable monitor mode on wire ...

  7. Aircrack-ng官方文档翻译[中英对照]---Aireplay-ng

    Aircrack-ng官方文档翻译---Aireplay-ng[90%] Description[简介] Aireplay-ng is used to inject frames. Aireplay- ...

  8. Retrofit官方文档翻译

    Retrofit官方文档翻译 官方文档网址 http://square.github.io/retrofit/ 介绍 Retrofit 将你的 HTTP API 转换为 Java 接口. public ...

  9. Spark官方文档翻译(一)~Overview

    Spark官方文档翻译,有问题请及时指正,谢谢. Overview页 http://spark.apache.org/docs/latest/index.html Spark概述 Apache Spa ...

随机推荐

  1. 使用dnsmasq快速搭建内网DNS

    背景介绍公司有一批测试服务器,之间希望通过自定义的域名进行访问,这样比较方便,但每个人每台机器都维护一个hosts的话会非常麻烦,于是想搭建一个内部的DNS服务器,对自定义的域名进行解析,同时缓存公网 ...

  2. Struts2.0 去掉action后缀名

    刚刚接触Struts2.0,发现默认请求都会带着后缀名:action 就如下图,url地址中会暴露login.action(请原谅struts拼写错误..) 作为一个URL简洁爱(chu)好(nv)者 ...

  3. 544B. Sea and Islands

    题目链接 题意: n*n的里面全是S的方格中,填充L,若填充的L上下左右都没有相邻的L则是一个快,问题是能否形成k个块 n可以去奇数也可以去偶数 只要我们输出满足条件的一个结果就好了 对于从0 - n ...

  4. Android核心分析之二十二Android应用框架之Activity

    3 Activity设计框架 3.1 外特性空间的Activity    我们先来看看,android应用开发人员接触的外特性空间中的Activity,对于AMS来讲,这个Activity就是客服端的 ...

  5. Haproxy均衡负载部署和配置文件详解

    HAproxy均衡负载部署和配置文件详解 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.根据官方数据,其最高极限支持10G ...

  6. Fatal error: cannot allocate memory for the buffer pool

    mysql有时候会被系统kill掉,原因是内存不够了,一般都是Ubuntu出现的,因为Ubuntu吃内存,你们又给的不多.. 咋解决呢? 重启服务器是可以的,起码暂时可以了, 可以考虑加内存,或者增加 ...

  7. http://www.360doc.com/content/12/1014/00/7471983_241330790.shtml

    http://www.360doc.com/content/12/1014/00/7471983_241330790.shtml

  8. Android百度地图开发04之POI检索

    POI检索 POI~~~ Point of Interest,翻译过来就是“兴趣点”.我们在使用地图的时候,搜索周边的ktv,饭店,或者宾馆的时候,输入关键字,然后地图展示给我们很多个点, 这些点就是 ...

  9. Java:IO流之字符流Reader、Writer详解

    java.io包中:字符流   字符流的两个抽象基类:   Reader         Writer   文件的读取:Reader抽象类(java.io包中) 直接子类的构造方法: FileRead ...

  10. 怎么批量修改Word表格的宽度

    怎么批量修改Word表格的宽度 怎么批量修改Word表格的宽度呢.Word表格可根据窗口自动调整表格宽度,使得所有的表格宽度和页面宽度一样.当页面设置了新的页边距后,所有的表格都需要调整新的宽度.或者 ...