查询会返回匹配特定条件的实体,使用GreenDao,你可以使用原生的SQL语句,也可以使用查询生成器(QueryBuilder)的API来生成查询。并且,查询也支持懒惰加载(lazy-loading)方式,这对于结果数目庞大的操作可能会节省内存提高性能。
1. QueryBuilder
QueryBuilder能够让你在不涉及SQL语句的情况下查询实体。写SQL有几个缺点,首先是易错的,其次是要在运行时才知道有没有问题(假如属性名是pid,你写成了id,也要到运营时才会崩溃),QueryBuilder能够在编译时检查错误(如属性的引用是否错误)。
例子:查询first name是"Joe"的人,得到的结果按照last name排序:
例子:查询first name是"Joe"并且出生在1970年10月份或之后的人:
也就是FirstName.eq("Joe") AND ( YearOfBirth.gt(1970) OR ( YearOfBirth.eq(1970) AND MonthOBirth.ge(10) ) )
请仔细观察括号的匹配。
我们看一下QueryBuilder.where函数的参数会发现,是一个变参函数(arg0, arg1...),这些参数是and关系
例子:加入购物车的生成如下:
每个商品的pid都是不同的。
购物车中商品prd的数量增加x:
2. Query (我理解为相当于SQL中的Prepare)
Query类是一个能够执行多次的查询语句,我理解为Prepare。
先查询1970年出生的Joe:
然后查询1977年出生的Maria:
3. LazyList
greenDao支持唯一结果和结果链表。如果你只想获取唯一的结果,那么可以使用unique(),它要么给你唯一一个结果,要么null,如果你不想获得null,那么你可以使用uniqueOrThrow(),它会在匹配结果为空时抛出DaoException的异常。
如果你想获取多个结果,以下有几个方案:
list():所有结果都会载入内存,结果会死一个ArrayList。
listLazy():结果会按需载入内存,一旦其中一个元素被要求了,那么就会载入内存并且进行chache,必须手动关闭。
还有listLazyUncached()和listIterator(),也需要手动通过调用close()来关闭。
4. 多线程执行查询
如果一个现成正在执行查询,另一个现成试图修改参数,会抛出异常。不要使用自己定义锁的机制,不然可能出现死锁。
尽量避免多线程执行查询,如果实在需要就使用forCurrentThread()来执行。
5. 原生查询(不建议使用)
1. QueryBuilder
QueryBuilder能够让你在不涉及SQL语句的情况下查询实体。写SQL有几个缺点,首先是易错的,其次是要在运行时才知道有没有问题(假如属性名是pid,你写成了id,也要到运营时才会崩溃),QueryBuilder能够在编译时检查错误(如属性的引用是否错误)。
例子:查询first name是"Joe"的人,得到的结果按照last name排序:
- List <User> items = userDao.queryBuilder()
- .where(Properties.FirstName.eq("Joe"))
- .orderAsc(Properties.LastName)
- .list();
也就是FirstName.eq("Joe") AND ( YearOfBirth.gt(1970) OR ( YearOfBirth.eq(1970) AND MonthOBirth.ge(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();
我们看一下QueryBuilder.where函数的参数会发现,是一个变参函数(arg0, arg1...),这些参数是and关系
例子:加入购物车的生成如下:
- Entity Cart = schema.addEntity("Cart");
- Cart.addIdProperty();
- Cart.addStringProperty("pid").notNull();
- Cart.addStringProperty("pcount").notNull();
购物车中商品prd的数量增加x:
- List<Cart> items = DbService.getInstance(getActivity()).queryCart(Properties.Pid.eq(prd));
- if (items.size() == 0) {
- DbService.getInstance(getActivity()).addToCart(new Cart(null,prd,x));
- Log.d("debug","success to add to cart, new item create");
- } else if (items.size() == 1) {
- Cart item = items.get(0);
- int c1 = Integer.valueOf(item.getPcount()).intValue();
- int c2 = Integer.valueOf(x).intValue();
- item.setPcount(Integer.toString(c1+c2));
- DbService.getInstance(getActivity()).updateCart(item);
- Log.d("debug","success to add to cart, item count modified");
- } else {
- Log.d("error","error to add to cart");
- }
2. Query (我理解为相当于SQL中的Prepare)
Query类是一个能够执行多次的查询语句,我理解为Prepare。
先查询1970年出生的Joe:
- Query query = userDao.queryBuilder().where(Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970)).build();
- List <User> joesOf1970 = query.list();
- query.setParameter(0, "Maria");
- query.setParameter(1, 1977);
- List <User> mariasOf1977 = query.list();
3. LazyList
greenDao支持唯一结果和结果链表。如果你只想获取唯一的结果,那么可以使用unique(),它要么给你唯一一个结果,要么null,如果你不想获得null,那么你可以使用uniqueOrThrow(),它会在匹配结果为空时抛出DaoException的异常。
如果你想获取多个结果,以下有几个方案:
list():所有结果都会载入内存,结果会死一个ArrayList。
listLazy():结果会按需载入内存,一旦其中一个元素被要求了,那么就会载入内存并且进行chache,必须手动关闭。
还有listLazyUncached()和listIterator(),也需要手动通过调用close()来关闭。
4. 多线程执行查询
如果一个现成正在执行查询,另一个现成试图修改参数,会抛出异常。不要使用自己定义锁的机制,不然可能出现死锁。
尽量避免多线程执行查询,如果实在需要就使用forCurrentThread()来执行。
5. 原生查询(不建议使用)
- queryRaw()
- queryRawCreate()