Android 数据库ORM框架GreenDao学习心得及使用总结<二>-阿里云开发者社区

开发者社区> wei-spring> 正文

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 plaincopy
 
  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 plaincopy
 
  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 plaincopy
 
  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 plaincopy
 
  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 plaincopy
 
  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 plaincopy
 
  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 plaincopy在CODE上查看代码片派生到我的代码片
 
  1. QueryBuilder.LOG_SQL = true;  
  2. QueryBuilder.LOG_VALUES = true;  

 

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

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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Android EventBus 3.0.0 使用总结
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/53065112 本文出自【赵彦军的博客】 前言 EventBus框架 EventBus是一个通用的叫法,例如Google出品的Guava,Guava是一个庞大的库,EventBus只是它附带的一个小功能,因此实际项目中使用并不多。
959 0
flutter网络dio框架公共请求参数、请求header使用总结
> 本文章将讲述 > 1.get请求中配置公共参数 > 2.post请求配置公共参数 > 3.请求header配置
541 0
Android Butterknife 8.4.0 使用方法总结
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/52983418 本文出自【赵彦军的博客】 前言 ButterKnife 简介 ButterKnife是一个专注于Android的View注入框架,可以减少大量的findViewById以及setOnClickListener代码,可视化一键生成。
926 0
Android存储之SQLite数据库
Android存储之SQLite数据库数据库 创建数据库 package ……; import android.
731 0
django的orm中F对象的使用
今天不巧就用上了。 就是将数据库的字段,自增1的场景。 from django.db.models import F DeployPool.objects.filter(name=deployversion_id).
1143 0
Android存储之SQLite数据库
Android存储之SQLite数据库数据库 创建数据库 package ……; import android.
523 0
使用iOS原生sqlite3框架对sqlite数据库进行操作(二)
使用iOS原生sqlite3框架对sqlite数据库进行操作
44 0
FFMPEG音频开发: Linux下采集摄像头(使用V4L2框架)数据录制成MP4视频保存到本地
FFMPEG音频开发: Linux下采集摄像头(使用V4L2框架)数据录制成MP4视频保存到本地
20 0
+关注
wei-spring
Android 开发,Java 开发,Python开发
366
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载