GreenDao讲义3:带你了解查询生成器和更加复杂的查询

来源:互联网 发布:js如何实现弹窗 编辑:程序博客网 时间:2024/06/08 15:00
查询会返回匹配特定条件的实体,使用GreenDao,你可以使用原生的SQL语句,也可以使用查询生成器(QueryBuilder)的API来生成查询。并且,查询也支持懒惰加载(lazy-loading)方式,这对于结果数目庞大的操作可能会节省内存提高性能。


1. QueryBuilder
QueryBuilder能够让你在不涉及SQL语句的情况下查询实体。写SQL有几个缺点,首先是易错的,其次是要在运行时才知道有没有问题(假如属性名是pid,你写成了id,也要到运营时才会崩溃),QueryBuilder能够在编译时检查错误(如属性的引用是否错误)。
例子:查询first name是"Joe"的人,得到的结果按照last name排序:
[java] view plaincopyprint?
  1. List <User> items = userDao.queryBuilder()  
  2. .where(Properties.FirstName.eq("Joe"))  
  3. .orderAsc(Properties.LastName)  
  4. .list();  
例子:查询first name是"Joe"并且出生在1970年10月份或之后的人:
也就是FirstName.eq("Joe") AND ( YearOfBirth.gt(1970) OR ( YearOfBirth.eq(1970) AND MonthOBirth.ge(10) ) )
[java] view plaincopyprint?
  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();  
请仔细观察括号的匹配。
我们看一下QueryBuilder.where函数的参数会发现,是一个变参函数(arg0, arg1...),这些参数是and关系
例子:加入购物车的生成如下:
[java] view plaincopyprint?
  1. Entity Cart = schema.addEntity("Cart");  
  2. Cart.addIdProperty();  
  3. Cart.addStringProperty("pid").notNull();  
  4. Cart.addStringProperty("pcount").notNull();  
每个商品的pid都是不同的。
购物车中商品prd的数量增加x:
[java] view plaincopyprint?
  1. List<Cart> items = DbService.getInstance(getActivity()).queryCart(Properties.Pid.eq(prd));  
  2. if (items.size() == 0) {  
  3.     DbService.getInstance(getActivity()).addToCart(new Cart(null,prd,x));  
  4.     Log.d("debug","success to add to cart, new item create");  
  5. else if (items.size() == 1) {  
  6.     Cart item = items.get(0);  
  7.     int c1 = Integer.valueOf(item.getPcount()).intValue();  
  8.     int c2 = Integer.valueOf(x).intValue();  
  9.     item.setPcount(Integer.toString(c1+c2));  
  10.     DbService.getInstance(getActivity()).updateCart(item);  
  11.     Log.d("debug","success to add to cart, item count modified");  
  12. else {  
  13.     Log.d("error","error to add to cart");  
  14. }  

2. Query (我理解为相当于SQL中的Prepare)
Query类是一个能够执行多次的查询语句,我理解为Prepare。
先查询1970年出生的Joe:
[java] view plaincopyprint?
  1. Query query = userDao.queryBuilder().where(Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970)).build();  
  2. List <User> joesOf1970 = query.list();  
然后查询1977年出生的Maria:
[java] view plaincopyprint?
  1. query.setParameter(0"Maria");  
  2. query.setParameter(11977);  
  3. List <User> mariasOf1977 = query.list();  


3. LazyList
greenDao支持唯一结果和结果链表。如果你只想获取唯一的结果,那么可以使用unique(),它要么给你唯一一个结果,要么null,如果你不想获得null,那么你可以使用uniqueOrThrow(),它会在匹配结果为空时抛出DaoException的异常。
如果你想获取多个结果,以下有几个方案:
list():所有结果都会载入内存,结果会死一个ArrayList。
listLazy():结果会按需载入内存,一旦其中一个元素被要求了,那么就会载入内存并且进行chache,必须手动关闭。
还有listLazyUncached()和listIterator(),也需要手动通过调用close()来关闭。


4. 多线程执行查询
如果一个现成正在执行查询,另一个现成试图修改参数,会抛出异常。不要使用自己定义锁的机制,不然可能出现死锁。
尽量避免多线程执行查询,如果实在需要就使用forCurrentThread()来执行。


5. 原生查询(不建议使用)
[java] view plaincopyprint?
  1. queryRaw()  
  2. queryRawCreate()  
0 0
原创粉丝点击