我正在寻找一种方法来进行需要JOIN的查询。有没有办法在准备好的声明中这样做,或者rawQuery
是我唯一的选择。如果rawQuery
是唯一选项,那么有没有办法自动将返回的对象映射到正在实现的Dao的对象。
我已经挖掘了文档和示例,但找不到任何可以将原始数据库结果映射到ORM对象类的内容。
答案 0 :(得分:16)
我正在寻找一种方法来进行需要JOIN的查询。
ORMLite支持simple JOIN queries。您也可以使用raw-queries来完成此任务。
您可以使用Dao.getRawRowMapper()
映射找到的查询,也可以创建自定义映射器。该文档包含以下示例代码,其中显示了如何将String[]
映射到您的对象:
GenericRawResults<Foo> rawResults =
orderDao.queryRaw(
"select account_id,sum(amount) from orders group by account_id",
new RawRowMapper<Foo>() {
public Foo mapRow(String[] columnNames,
String[] resultColumns) {
return new Foo(Long.parseLong(resultColumns[0]),
Integer.parseInt(resultColumns[1]));
}
});
答案 1 :(得分:9)
我找到了一种将结果集自动映射到模型对象的方法。
// return the orders with the sum of their amounts per account
GenericRawResults<Order> rawResults =
orderDao.queryRaw(query, orderDao.getRawRowMapper(), param1)
// page through the results
for (Order order : rawResults) {
System.out.println("Account-id " + order.accountId + " has "
+ order.totalOrders + " total orders");
}
rawResults.close();
关键是使用Dao
从对象getRawRowMapper()
中提取行映射器,它将为您处理映射。我希望这有助于任何找到它的人。
我仍然喜欢在QueryBuilder
内加入联盟的能力,但在支持之前,这是我认为的下一个最好的事情。
答案 2 :(得分:0)
原始查询自动映射
我遇到了自定义SELECT映射字段的问题,这些字段返回任何表模型中不存在的列。所以我制作了自定义RawRowMapper
,可以将字段从自定义查询映射到自定义模型。当您的查询具有与任何表maping模型不对应的字段时,这非常有用。
这是执行查询自动映射的 RowMapper :
public class GenericRowMapper<T> implements RawRowMapper<T> {
private Class<T> entityClass;
private Set<Field> fields = new HashSet<>();
private Map<String, Field> colNameFieldMap = new HashMap<>();
public GenericRowMapper(Class<T> entityClass) {
this.dbType = dbType;
this.entityClass = entityClass;
Class cl = entityClass;
do {
for (Field field : cl.getDeclaredFields()) {
if (field.isAnnotationPresent(DatabaseField.class)) {
DatabaseField an = field.getAnnotation(DatabaseField.class);
fields.add(field);
colNameFieldMap.put(an.columnName(), field);
}
}
cl = cl.getSuperclass();
} while (cl != Object.class);
}
@Override
public T mapRow(String[] columnNames, String[] resultColumns) throws SQLException {
try {
T entity = entityClass.newInstance();
for (int i = 0; i < columnNames.length; i++) {
Field f = colNameFieldMap.get(columnNames[i]);
boolean accessible = f.isAccessible();
f.setAccessible(true);
f.set(entity, stringToJavaObject(f.getType(), resultColumns[i]));
f.setAccessible(accessible);
}
return entity;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public Object stringToJavaObject(Class cl, String result) {
if (result == null){
return null;
}else if (cl == Integer.class || int.class == cl) {
return Integer.parseInt(result);
} else if (cl == Float.class || float.class == cl) {
return Float.parseFloat(result);
} else if (cl == Double.class || double.class == cl) {
return Double.parseDouble(result);
} else if (cl == Boolean.class || cl == boolean.class) {
try{
return Integer.valueOf(result) > 0;
}catch (NumberFormatException e){
return Boolean.parseBoolean(result);
}
} else if (cl == Date.class) {
DateLongType lType = DateLongType.getSingleton();
DateStringType sType = DateStringType.getSingleton();
try {
return lType.resultStringToJava(null, result, -1);
} catch (NumberFormatException e) {
try {
return sType.resultStringToJava(null, result, -1);
} catch (SQLException e2) {
throw new RuntimeException(e);
}
}
} else {
return result;
}
}
}
这是用法:
class Model{
@DatabaseField(columnName = "account_id")
String accId;
@DatabaseField(columnName = "amount")
int amount;
}
String sql = "select account_id,sum(amount) amount from orders group by account_id"
return queryRaw(sql,new GenericRowMapper<>(Model.class)).getResults()
如果查询列名称与List<Model>
相同,则会将带有映射结果行的@DatabaseField(columnName
返回给Model