GreenDao講義3:帶你瞭解查詢生成器和更加複雜的查詢

查詢會返回匹配特定條件的實體,使用GreenDao,你可以使用原生的SQL語句,也可以使用查詢生成器(QueryBuilder)的API來生成查詢。並且,查詢也支持懶惰加載(lazy-loading)方式,這對於結果數目龐大的操作可能會節省內存提高性能。


1. QueryBuilder
QueryBuilder能夠讓你在不涉及SQL語句的情況下查詢實體。寫SQL有幾個缺點,首先是易錯的,其次是要在運行時才知道有沒有問題(假如屬性名是pid,你寫成了id,也要到運營時纔會崩潰),QueryBuilder能夠在編譯時檢查錯誤(如屬性的引用是否錯誤)。
例子:查詢first name是"Joe"的人,得到的結果按照last name排序:
  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) ) )
  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關係
例子:加入購物車的生成如下:
  1. Entity Cart = schema.addEntity("Cart");  
  2. Cart.addIdProperty();  
  3. Cart.addStringProperty("pid").notNull();  
  4. Cart.addStringProperty("pcount").notNull();  
每個商品的pid都是不同的。
購物車中商品prd的數量增加x:
  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:
  1. Query query = userDao.queryBuilder().where(Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970)).build();  
  2. List <User> joesOf1970 = query.list();  
然後查詢1977年出生的Maria:
  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. 原生查詢(不建議使用)
  1. queryRaw()  
  2. queryRawCreate()  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章