8

我正在寻找一种方法来进行需要 JOIN 的查询。有没有办法在准备好的声明中做到这一点,或者是rawQuery我唯一的选择。如果rawQuery是唯一的选择,那么是否有某种方法可以自动将返回的对象映射到正在实现的 Dao 的对象。

我翻阅了文档和示例,但找不到任何可以让我将原始数据库结果映射到 ORM 对象类的内容。

4

3 回答 3

17

我正在寻找一种方法来进行需要 JOIN 的查询。

ORMLite 支持简单的 JOIN 查询。您也可以使用原始查询来完成此操作。

您可以使用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]));
        }
    });
于 2012-08-20T19:12:54.277 回答
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();

关键是使用 将行映射器从您的对象中拉出DaogetRawRowMapper()它将为您处理映射。我希望这对找到它的人有所帮助。

我仍然希望能够在其中进行连接,QueryBuilder但在得到支持之前,我认为这是下一个最好的事情。

于 2012-08-20T18:25:12.043 回答
1

原始查询自动映射

我遇到了从自定义 SELECT 映射字段的问题,这些字段返回任何表模型中都不存在的列。所以我做了自定义RawRowMapper,可以将自定义查询中的字段映射到自定义模型。当您的查询具有不对应于任何表映射模型的字段时,这很有用。

这是执行查询自动映射的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

于 2016-07-26T09:47:16.540 回答