在Android中使用CursorAdapter和ORMLite

13

我正在修改我的Android应用程序,以便与ORMLite一起使用。目前,它使用了许多CursorAdapters,我希望尽量保持这些适配器以最小化编码。

我不是100%确定,但似乎当ORMLite在数据库中创建一个id字段时,它总是使用id,而CursorAdapter需要_id

可以通过以下查询来解决这个问题:

select id as _id ......

但是Dao.queryRaw()方法返回的是一个列表,而不是Cursor,所以我采用了另一个SQLiteOpenHelper数据库连接并使用rawQuery()的方式来实现。

这种方法可行,但是否有更好的方法呢?拥有两个独立的数据库连接似乎过于冗余,或许会在后面带来麻烦。


抱歉,看起来这个问题是虚假的。我错了,使用ORMLite可以为列命名_id,所以我建议删除这个问题,以避免混淆,除非有人很快有进一步的添加.. - Stev_k
2
与其删除它,我建议您回答并说明您是如何解决的 - 某些人可能会发现这很有帮助,特别是关于如何创建与ORM一起使用的光标的代码示例。 - pjco
1
已经完成了。你是对的 - 没有必要删除,我只是担心人们会偶然发现这种错误信息并且它会让人们迷失方向,但答案是仔细阅读! - Stev_k
3个回答

11

您的评论表明您已经回答了自己的问题。 您可以使用ORMLite创建一个名为"_id"的列:

@DatabaseField(generatedId = true)
private int _id;
或者
@DatabaseField(generatedId = true, columnName = "_id")
private int id;

如果您正在使用Cursor,则可能需要查看DatabaseResults类上的last()moveAbsolute(...)方法。此外,AndroidDatabaseResults(可以强制转换)还具有getRawCursor()方法,该方法返回基础Cursor对象,并具有额外的getCount()getPosition()方法。

以下是有关ORMLite和Cursor的更多信息:

  

使用ORMLite的Android Cursor在CursorAdapter中使用

您可以使用以下代码访问Cursor

// build your query
QueryBuilder<Foo, String> qb = fooDao.queryBuilder();
qb.where()...;
// when you are done, prepare your query and build an iterator
CloseableIterator<Foo> iterator = dao.iterator(qb.prepare());
try {
   // get the raw results which can be cast under Android
   AndroidDatabaseResults results =
       (AndroidDatabaseResults)iterator.getRawResults();
   Cursor cursor = results.getRawCursor();
   ...
} finally {
   iterator.closeQuietly();
}

3
我刚刚意识到在使用游标时不能关闭迭代器(我猜的)。你要如何处理?是在onDestroy()函数中继续保持它并关闭它吗? - Sebastian
2
如果它是一个急切获取的集合,它不需要被关闭。如果它是一个懒惰的集合,那么连接将保持打开状态,并且您需要关闭它。如果您在Android CursorAdapter中,则不确定如何执行此操作@Sebastian。 - Gray
抱歉问一个新手问题:默认情况下是否有一种惰性集合?我遇到了与@Sebastian相同的问题,当光标正在使用时关闭迭代器会导致崩溃。现在我正在从Datamanager类传递游标到列表片段和自定义游标适配器。它可以工作,但我不确定何时何地释放迭代器。 - jannej
懒加载是默认设置。请参见此处:http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/field/ForeignCollectionField.html#eager() - Gray

5

结果证明,我确实需要使用ORMLite进行原始SQL查询,因为我需要进行左连接(即不是由于必须在查询中重命名id列而导致的,根据Gray上面的答案,这是不必要的)。

我所做的方法如下:

public class DatabaseHelper extends OrmLiteSqliteOpenHelper{
   public void myRawQueryMethod() {
        SQLiteDatabase database = this.getReadableDatabase();
        String SqlQuery = "Write raw SQL query here"; 
        Cursor cursor = database.rawQuery(SqlQuery, null);
    }
}

感谢您的建议。

FYI:我们已经在ORMLite的4.22版本中添加了LEFT JOIN功能。该版本刚刚发布。 - Gray

0

将您的光标包装在另一个光标中,该光标将"_id"视为您真正的主键列的别名。例如:

cursor = new CursorWrapper(cursor) {
                @Override
                public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {
                    if ("_id".equals(columnName)) columnName = "id";
                    return super.getColumnIndexOrThrow(columnName);
                }
            };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接