GreenDao简明教程(查询,Querying)

亲测可用,若有疑问请私信

这是一篇关于greenDao的简明使用教程(其实就是官网tutorial的一个大概的翻译)。

一共有四篇,链接如下:

1.基本介绍

2.实体建模

3.查询

4.关系

查询

查询接口返回符合指定条件的实体对象集合.你可以使用SQL组织你的查询语句,或者采用更好的方法,使用greenDao的QueryBuilder API.greenDao的查询也支持延迟加载结果,当结果集很大的时候,它会节省内存和提高性能.

1.QueryBuilder

QueryBuilder类让你不需要写SQL来构建查询条件.写SQL大多数人都不喜欢,并且容易出错,因为它需要在运行时才能反馈错误.QueryBuilder容易使用并且不需要写SQL.使用它,相比只想代码不容易产生bug,它的语法在编译时候就会检查完.以greenDao为基础的代码生成的方法,使编译时的检查项能包括每一个属性的引用.
例如:查询以Joe为名,以姓排序的所有用户.

 
  1. List joes = userDao.queryBuilder()

  2. .where(Properties.FirstName.eq("Joe"))

  3. .orderAsc(Properties.LastName)

  4. .list();

嵌套条件的例子:获取出生在1970年10月以后名为Joe的所有用户. 我们将用户生日对应到实体的年、月、日属性.我们使用更正式的形式将查询条件表达为:名是Joe AND(生日的年份大于1970 OR(生日的年是1970 AND 生日的月等于或大于10))

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

2.Query类和LazyList类

Query类对象代表一个可以被多次执行的查询.当你使用QueryBuilder中的一个方法来获取结果(如一个list()方法),QueryBuilder内部使用Query类.如果你要以相同的条件多次查询,你可以调用QueryBuilder的build()方法来产生一个Query,不需要执行它.
greenDao支持唯一结果(0或1个结果)、和多个结果的查询.如果你期望唯一的结果,调用Query或者QueryBuilder的unique()方法,它会给你唯一的结果或者null(如果没有找到匹配的实体).如果你的情况不允许null作为结果,调用uniqueOrThrow(),它会保证返回非空的实体(如果没有匹配的结果,它会抛出DaoException异常).
如果查询时你期望返回多个结果,你可以调用list...中的一个方法:

:--:|:--:
list()|所有实体加载到内存.结果是一个典型的ArrayList.容易使用
listLazy()|实体根据需要加载到内存.一旦列表中一个元素被使用,这个元素会被加载和缓存起来,给后续重复使用.使用完后需要关闭 listLazyUncached()|一个虚拟的实体列表:任何请求列表中的元素将会触发从数据库加载数据.使用后必须关闭 listIterator()|让你使用迭代器来遍历结果集,它根据需要加载数据(延迟加载).数据没有缓存,使用后必须关闭

listLazy、listLazyUncached和listIterator 使用了greenDao的LazyList类.为了使用时才加载数据,它保存了数据库游标的引用.这也是使用后必须调用关闭方法的原因(一般在try/finally代码块中关闭).一旦所有的元素被访问或遍历到,listLazy()返回有缓存、延迟加载列表和listIterator()返回的延迟加载迭代器会自动关闭数据库游标.如果数据的访问过早的结束了(没有遍历完全),那么关闭数据库游标是你要做的的工作.

3.使用Queries进行多次查询

一旦你使用QueryBuilder构造了一个query,这个query对象后续可以重复使用,来执行查询.这比总是创建新的Query对象要更有效.如果查询条件没有变,你只需要再次调用其中一个list/unique方法.如果参数有改变,你必须对改变的参数调用setParameter方法.目前,各个参数以0开始的索引来区分.对应你传入参数到QueryBuilder的索引.
下面的例子使用Query对象来查询"名"为Joe,出生在1970年的用于:

 
  1. Query query = userDao.queryBuilder().where(

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

  3. .build();

  4. List joesOf1970 = query.list();

使用这个Query对象,我们查找名为Marias,出生在1977年的用户:

 
  1. query.setParameter(0, "Maria");

  2. query.setParameter(1, 1977);

  3. List mariasOf1977 = query.list();

4.在多线程中执行查询

如果你想在多线程中使用查询,你必须对query对象调用forCurrentThread()方法来获取一个当前线程的Query实例.从greenDao1.3以后,Query的实例对象绑定到构建query的线程中.这样,你可以安全的对Query对象设置参数而不受其他线程的干扰.如果其他线程试图对query对象设置参数或者执行绑定在其他线程的查询,greenDao会抛出异常.这样,你就不需要使用同步语句.事实上,我们应该避免使用锁,因为如果并发事务使用同一个Query对象,它会导致死锁.
为了完全避免潜在的死锁,greenDao1.3引入了forCurrentThread()函数.它会返回本线程的Query实例,它在当前线程可以安全的使用.每次调用forCurrentThread(),传入的参数和使用QueryBuilder构造Query的参数一致.

5.原始查询

获取数据,有两种方法来执行原始的SQL.比较好的方法是使用QueryBuilder和WhereCondition.StringCondition. 使用它,你可以向QueryBuilder传入任何的SQL WHERE子句片段.下面的代码是一个笨拙的方法,它让你使用一个select子句来起到join的效果

 
  1. Query query = userDao.queryBuilder().where(

  2. new StringCondition("_ID IN " +

  3. "(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();

碰到QueryBuilder没有提供你需要的特性时(例如上面的join关键字),你可以回到原始的查询语句或者原始查询语句的构造方法.他们允许传入原始SQL字符串,追加到SELECT + 实体列名后面.通过这种方法,你可以拼好任意WHERE和ORDER BY子句,来查询数据库中的对象.实体表名用别名"T"来称呼:
下面的例子展示了如何使用join创建query对象,它查找组名为"admin"的用户群.

 
  1. Query query = userDao.queryRawCreate(

  2. ", GROUP G WHERE G.NAME=? AND T.GROUP_ID=G._ID", "admin");

注意:你可以使用生成的常量来指向表和列名.这是推荐的做法,它可以避免错别字,因为编译器会检查名字.在实体对应的Dao类中,你会找到TABLENAME,它持有数据库表的名字.Dao类中还有一个Properties内部类 ,包含所有的属性常量(对应数据库列名).

6.删除查询

批量删除会删除符合条件的实体.想要行批量删除,需要创建一个QueryBuilder,调用它的buildDelete方法,执行返回的DeleteQuery.这部分的api将来可以会修改,例如,会添加便利的方法.记住,批量删除目前不会影响identity scope中的实体,例如实体已经有缓存并且是调用传入ID来获取的函数,你可以"复活"他们.如果这里给你的情况带来一些问题,你可以考虑清除identity scope.

7.查找查询中的问题

你的查询没有返回你期望的值?这里有2个静态的标识,一个是将sql语句打印出来,一个是将传入QueryBuilder的参数打印出来:

 
  1. QueryBuilder.LOG_SQL = true;

  2. QueryBuilder.LOG_VALUES = true;

这些日志会记录生成的sql命令和调用build()方法传入的参数.这样你可以对比他们是不是你预期的.这也帮助你们拷贝sql语句到其他数据库浏览工具,并执行他们获取结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值