Android 数据库ORM框架GreenDao学习心得及使用总结<二>

简介: 转:http://blog.csdn.net/xushuaic/article/details/24496191   第五篇 查询 查询会返回符合某些特定标准的实体。你可以使用原始的SQL定制查询语句,或者更好的方式:使用GreenDao的QueryBuilder API。

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

 

第五篇 查询

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

 

QueryBuilder

 

QueryBuilder可以帮助你构建自定义的查询语句,而不使用SQL的情况。并不是每个人都喜欢书写SQL语句,当然很容易就会出一些错,这些错误只有在运行的时候才会被发现。而QueryBuilder很容易使用,节省了你书写SQL语句的时间。当然,由于语法的检验是在编译时才执行,所以在查询语句中发现bug是很困难的。

QueryBuilder的编译时间会检验属性的引用,这样能够在greenDao后面,通过代码生成的方法发现bug。

比如:查找所有以“Joe”为first name 的用户,并以last name排序:

 

[java]  view plain copy
 
  1. List joes = userDao.queryBuilder()  
  2. .where(Properties.FirstName.eq("Joe"))  
  3. .orderAsc(Properties.LastName)  
  4. .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).

[java]  view plain copy
 
  1. QueryBuilder qb = userDao.queryBuilder();  
  2. qb.where(Properties.FirstName.eq("Joe"),  
  3. qb.or(Properties.YearOfBirth.gt(1970),  
  4. qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));  
  5. 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 的用户:

 

[java]  view plain copy
 
  1. Query query = userDao.queryBuilder().where(  
  2. Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970))  
  3. .build();  
  4. List joesOf1970 = query.list();  

 

 

使用query对象,可以查询

 

[java]  view plain copy
 
  1. query.setParameter(0, "Maria");  
  2. query.setParameter(1, 1977);  
  3. 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片段。

下面是一个笨拙的例子展示如果使用这种方式进行一个替代联合查询的子查询。

[java]  view plain copy
 
  1. Query query = userDao.queryBuilder().where(  
  2. new StringCondition("_ID IN " +  
  3. "(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

 

[java]  view plain copy
 
  1. 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。

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. QueryBuilder.LOG_SQL = true;  
  2. QueryBuilder.LOG_VALUES = true;  

 

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

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

目录
相关文章
|
23天前
|
算法 JavaScript Android开发
|
2月前
|
Java 程序员 API
Android|集成 slf4j + logback 作为日志框架
做个简单改造,统一 Android APP 和 Java 后端项目打印日志的体验。
101 1
|
3月前
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
380 3
|
3月前
|
编译器 Android开发 开发者
带你了解Android Jetpack库中的依赖注入框架:Hilt
本文介绍了Hilt,这是Google为Android开发的依赖注入框架,基于Dagger构建,旨在简化依赖注入过程。Hilt通过自动化的组件和注解减少了DI的样板代码,提高了应用的可测试性和可维护性。文章详细讲解了Hilt的主要概念、基本用法及原理,帮助开发者更好地理解和应用Hilt。
85 8
|
17天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
32 1
|
19天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
33 4
|
2月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
64 3
Mysql(4)—数据库索引
|
26天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
143 1
|
28天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
83 2
|
1月前
|
存储 关系型数据库 MySQL
MySQL vs. PostgreSQL:选择适合你的开源数据库
在众多开源数据库中,MySQL和PostgreSQL无疑是最受欢迎的两个。它们都有着强大的功能、广泛的社区支持和丰富的生态系统。然而,它们在设计理念、性能特点、功能特性等方面存在着显著的差异。本文将从这三个方面对MySQL和PostgreSQL进行比较,以帮助您选择更适合您需求的开源数据库。
115 4