转载地址:http://my.oschina.net/cheneywangc/blog/196360

上一篇中我们讲述了如何创建generator工程以及如何在android工程中使用。那么在这篇中就重点讲述下使用篇,主要针对数据库查询操作。


1. 查询 -- Queries

    1)你可以使用原生的SQl(raw sql)语句;

    2)也可以使用推荐的方法:使用greenDAO提供的QueryBuilder的API。

    3)查询还支持结果延迟加载(lazy-loading),主要为操作较大查询结果是节约内存并提高性能。


(1)QueryBuilder

    使用过sql语句查询的人都会有一种感触(主要针对不是专职开发数据库并对sql不是很熟练的人),写起来复杂、不能再第一时间发现问题(只能在运行过程中验证sql的正确性)、查找bug麻烦等等。QueryBuilder的出现就是为了解决sql使用的问题,提高开发效率。

看一个略微复杂的例子,查询first name是Joe,并在1970年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();


不用我来解释了吧。


(2)Lazylist

    greenDAO支持返回唯一查询结果(如果没有返回null) ---- 调用Query或QueryBuilder的unique()方法;

    也支持返回list ---- 调用list()方法。

    当不希望返回null作为结果时,则调用uniqueOrThrow()方法,当结果null时将直接抛出异常。

返回多个结果解释:

list():     所有entity均会被加载到内存中。结果仅是一个简单的ArrayList。使用最简单。

listLazy():    查询结果会根据需要加载到内存中。列表中的元素仅在accessed for the first time,它才会被加载并缓存。该方法必须主动关闭(Must be closed)。

listLazyUncached():    虚拟的结果列表,任何对元素的方法实际都会到数据库中去加载数据。Must be closed

listIterator():    根据需要迭代结果(lazily)。数据不缓存。Must be closed


在greenDAO实现中,后3中其实都使用的LazyList类。为了实现根据需要加载,其内部实现上是保存了数据库cursor的引用。这也是为何这3中方式must be closed,其就是为了释放内部cursor和迭代器(通常是在try-finally块中完成close)。


(3)Query

    解释:Query类代表了一个可以被重复执行的查询。在QueryBuilder内部其实也是会定义一个Query并执行完成查询。

    这将带来极大地方便,因为任何人都不希望在每次查询的时候总是写一遍query代码。同时Query还可以根据需要改变参数。如下实例代码:

    使用Query对象查询名为Joe并出生在1970年的人:

Query query = userDao.queryBuilder().where(

Properties.FirstName.eq("Joe")Properties.YearOfBirth.eq(1970))

.build();

List joesOf1970 = query.list();

然后想再查询出生在1977年之后并叫Marias的人:

query.setParameter(0"Maria");

query.setParameter(11977);

List mariasOf1977 = query.list();

注意:参数的编号是创建query所设置的顺序。


(4)多线程查询

    有时我们希望在多线程中执行查询。从greenDAO 1.3版本开始,实例化Query对象均会绑定到其自己的线程,这样我们就可以安全的设置Query参数,因为其他线程无法影响到。如果其他线程使用别的线程的query(比如设置参数、执行查询)将会抛出异常。因此,我们也不需要做同步工作,而且不要加锁,因为加入相关的事务用到了该Query对象将导致死锁。

    为完全地避免可能产生的死锁,1.3版本引入了forCurrentThread()方法。该方法将返回本线程内的Query实例,每次调用该方法时,参数均会被重置为最初创建时的一样。


(5)原生sql查询

    推荐的方法执行原生sql语句是通过QueryBuilder和WhereCondition.StringCondition。如下代码:

Query query = userDao.queryBuilder().where(

new StringCondition("_ID IN " "(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();

    假如QueryBuilder没有提供你需要的特性,你也可以使用queryRaw() 和 queryRawCreate() 方法。具体就不再详细介绍了。


(6)删除操作(delete query)

    删除操作会删除所有满足条件的实体。为实现批量删除(bulk delete),调用QueryBuilder的 buildDelete方法并执行DeleteQuery。该部分API还不稳定,可能会改变就不介绍了。


(7)问题定位(日志

    你可能会遇到查询结果并不是预期的那样,这时候你就可以设置两个静态flag参数来打日志定位问题:

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

    这将会将产生的sql命令以及传递的参数以日志方式输出,由此方便程序员定位问题。


更多相关文章

  1. Instant Run详解
  2. 《一》Android(安卓)数据库 SQlite SQLiteOpenHelper
  3. Android(安卓)Mini音乐播放器[简单版本]
  4. 你真的懂Handler吗?Handler问答
  5. Android中的Service详解
  6. Android系列教程(1):Notification 与状态栏信息
  7. Android(安卓)framework层实现实现wifi无缝切换AP
  8. Android(安卓)SQLiteOpenHelper源码解读
  9. android的消息队列机制

随机推荐

  1. 周杰伦新歌《说好不哭》深夜上线挤崩QQ音
  2. 承认吧,程序员就是比你有钱,又比你会过日子
  3. Java程序员必备基础:Object的十二个知识点
  4. Steam将上架KFC恋爱模拟器,你要和肯德基老
  5. 聊聊如何从程序员晋升为管理者(我的肺腑之
  6. 「什么值得买」网站挂了,疑程序员删库跑路
  7. MySQL也要删“blacklist”,万万没想到技术
  8. JAVA程序一次句柄泄露问题分析
  9. 微信转账后被拉黑该如何追回?官方这些隐藏
  10. 一大波开发者福利!谷歌宣布在中国正式推出