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