rawQuery 中的 ORMLite 别名

ORMLite alias in rawQuery

是否可以在 Android 中的 ORMLite 查询中使用别名 (AS)?我正在尝试将它与以下代码一起使用:

String query =
        "SELECT *, (duration - elapsed) AS remaining FROM KitchenTimer ORDER BY remaining";
GenericRawResults<KitchenTimer> rawResults =
        getHelper().getKitchenTimerDao().queryRaw(
                query, getHelper().getKitchenTimerDao().getRawRowMapper());

但是当执行这段代码时,会出现以下错误:

java.lang.IllegalArgumentException: Unknown column name 'remaining' in table kitchentimer

java.lang.IllegalArgumentException: Unknown column name 'remaining' in table kitchentimer

与您的 KitchenTimerDao 关联的原始行映射器期望结果直接对应于 KitchenTimer 实体列。但是,由于您正在添加 remaining 列,因此没有地方可以放置该结果列,因此出现异常。这是一个原始查询,因此您需要提出自己的结果映射器——您不能使用 DAO 的。见 docs on raw queries.

例如,如果您想将结果映射到您自己的对象中 Foo,那么您可以这样做:

String query =
    "SELECT *, (duration - elapsed) AS remaining FROM KitchenTimer ORDER BY remaining";
GenericRawResults<Foo> rawResults =
    orderDao.queryRaw(query, new RawRowMapper<Foo>() {
        public Foo mapRow(String[] columnNames, String[] resultColumns) {
            // assuming 0th field is the * and 1st field is remaining
            return new Foo(resultColumns[0], Integer.parseInt(resultColumns[1]));
        }
     });
// page through the results
for (Foo foo : rawResults) {
   System.out.println("Name " + foo.name + " has " + foo.remaining + " remaining seconds");
}
rawResults.close();

我遇到了同样的问题。我想获得一个对象列表,但添加了一个带有别名的新属性。

为了继续使用 OrmLite 中的对象映射器,我使用了 RawRowMapper 来接收列和结果。但是我没有手动转换所有列,而是先读取别名并删除它在列数组中的引用。那么就可以使用OrmLite Dao mapper了。

我用Kotlin代码写的:

val rawResults = dao.queryRaw<Foo>(sql, RawRowMapper { columnNames, resultColumns ->

                // convert array to list
                val listNames = columnNames.toMutableList()
                val listResults = resultColumns.toMutableList()

                // get the index of the column not included in dao
                val index = listNames.indexOf(ALIAS)
                if (index == -1) {
                    // There is an error in the request because Alias was not received
                    return@RawRowMapper Foo()
                }

                // save the result
                val aliasValue = listResults[index]

                // remove the name and column
                listNames.removeAt(index)
                listResults.removeAt(index)

                // map row
                val foo = dao.rawRowMapper.mapRow(
                    listNames.toTypedArray(), 
                    listResults.toTypedArray()
                ) as Foo

                // add alias value. In my case I save it in the same object 
                // but another way is to create outside of mapping a list and 
                // add this value in the list if you don't want value and object together
                foo.aliasValue = aliasValue

                // return the generated object
                return@RawRowMapper foo
            })

这不是最短的解决方案,但对我来说,继续使用相同的映射器非常重要。它可以避免在将属性添加到 table 并且您不记得更新映射时出现错误。