最近在Android手機開發中使用了ORM框架Sugar1.4,節省了大量代碼,同時也遇到不少麻煩,記錄如下: 1. 使用group by將查詢結果轉換為POJO對象 在Sugar1.4中,可以使用如下代碼將查詢結果轉換為POJO對象。 該方法會調用SugarRecord類的inflate方法,如下 ...
最近在Android手機開發中使用了ORM框架Sugar1.4,節省了大量代碼,同時也遇到不少麻煩,記錄如下:
1. 使用group by將查詢結果轉換為POJO對象
在Sugar1.4中,可以使用如下代碼將查詢結果轉換為POJO對象。
List<POJO> results = SugarRecord.findWithQuery(POJO.class, sql);
1.1. 額外的ID欄位
該方法會調用SugarRecord類的inflate方法,如下:
1 private static void inflate(Cursor cursor, Object object, Map<Object, Long> entitiesMap) { 2 List<Field> columns = ReflectionUtil.getTableFields(object.getClass()); 3 if (!entitiesMap.containsKey(object)) { 4 entitiesMap.put(object, cursor.getLong(cursor.getColumnIndex(("ID")))); 5 } 6 7 for (Field field : columns) { 8 field.setAccessible(true); 9 Class<?> fieldType = field.getType(); 10 if (isSugarEntity(fieldType)) { 11 try { 12 long id = cursor.getLong(cursor.getColumnIndex(NamingHelper.toSQLName(field))); 13 field.set(object, (id > 0) ? findById(fieldType, id) : null); 14 } catch (IllegalAccessException e) { 15 e.printStackTrace(); 16 } 17 } else { 18 ReflectionUtil.setFieldValueFromCursor(cursor, field, object); 19 } 20 } 21 }
註意第4行代碼,會在entitiesMap中緩存查詢結果與ID,所以在構造查詢語句sql的時候,需要額外增加一個ID欄位。
1.2. SQLite大小寫敏感問題
在Sugar官方文檔中,類欄位通過下劃線命名法映射到數據表的對應列(見上代碼12行NamingHelper)。
查看NamingHelper源碼,其返回結果為大寫,但官方示例的條件查詢中全部都使用的小寫,由於SQLite一般類型列大小寫不敏感,所以在一般情況下是沒有問題的。
但是!當在SQL中使用AS語法重命名後,就大小寫敏感了!
所以在group by查詢中,必須將彙總列重命名為大寫的下劃線命名,才能在Sugar中映射到POJO實例的對應列。
1.3. SQLite不支持IF語法
SQLite不支持IF語法,但可以使用CASE WHEN語法代替。
CASE WHEN first conditional expression THEN column value WHEN second conditional expression THEN column value WHEN third conditional expression THEN column value END CASE WHEN conditional expression THEN column value ELSE default column value END