最近在Android手机开发中使用了ORM框架Sugar1.4,节省了大量代码,同时也遇到不少麻烦,记录如下:
1. 使用group by将查询结果转换为POJO对象
在Sugar1.4中,可以使用如下代码将查询结果转换为POJO对象。
List<POJO> results = SugarRecord.findWithQuery(POJO.class, sql);
1.1. 额外的ID字段
该方法会调用SugarRecord类的inflate方法,如下:
private static void inflate(Cursor cursor, Object object, Map<Object, Long> entitiesMap) {
List<Field> columns = ReflectionUtil.getTableFields(object.getClass());
if (!entitiesMap.containsKey(object)) {
entitiesMap.put(object, cursor.getLong(cursor.getColumnIndex(("ID"))));
} for (Field field : columns) {
field.setAccessible(true);
Class<?> fieldType = field.getType();
if (isSugarEntity(fieldType)) {
try {
long id = cursor.getLong(cursor.getColumnIndex(NamingHelper.toSQLName(field)));
field.set(object, (id > 0) ? findById(fieldType, id) : null);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
ReflectionUtil.setFieldValueFromCursor(cursor, field, object);
}
}
}
注意第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