我在Android中使用Sqlite并从数据库中获取值,我使用类似这样的内容:
Cursor cursor = sqliteDatabase.rawQuery("select title,category from table", null);
int columnIndexTitle = cursor.getColumnIndex("title");
iny columnIndexCategory = cursor.getColumnIndex("category");
cursor.moveToFirst();
while (cursor.moveToNext()) {
String title = cursor.getString(columnIndexTitle);
String category = cursor.getString(columnIndexCategory);
}
cursor.close();
我想创建自己的Cursor,以便我可以使用一种方法执行getColumnIndex()
和getString()
。像这样:
String title = cursor.getString("title");
我想创建自己的类来扩展我从sqliteDatabase.rawQuery
得到的光标,但我不知道如何实现这一点。我应该扩展SQLiteCursor还是应该如何做?它甚至可能是一个好主意吗?
答案 0 :(得分:4)
我遇到了这个问题,寻找创建自定义Cursor
以与SQLiteDatabase
一起使用的最佳方法。在我的情况下,我需要一个额外的属性Cursor来携带一个额外的信息,所以我的用例并不完全像问题的主体。发表我的发现希望它会有所帮助。
对我来说棘手的部分是SQLiteDatabase查询方法返回一个Cursor,我需要将一个自定义子类传递给Cursor。
我在Android API中找到了解决方案:使用CursorWrapper类。它似乎是为此而设计的。
班级:
public class MyCustomCursor extends CursorWrapper {
public MyCustomCursor(Cursor cursor) {
super(cursor);
}
private int myAddedAttribute;
public int getMyAddedAttribute() {
return myAddedAttribute;
}
public void setMyAddedAttribute(int myAddedAttribute) {
this.myAddedAttribute = myAddedAttribute;
}
}
用法:
public MyCustomCursor getCursor(...) {
SQLiteDatabase DB = ...;
Cursor rawCursor = DB.query(...);
MyCustomCursor myCursor = new MyCustomCursor(rawCursor);
myCursor.setMyAddedAttribute(...);
return myCursor;
}
答案 1 :(得分:3)
创建自己的getString将导致每个调用的地图查找,而不仅仅是getColumnIndex。
这是the code for SQLiteCursor.getColumnIndex和AbstractCursor.getColumnIndex。如果你有很多行,减少对这个函数的调用将防止不必要的字符串处理和映射查找。
答案 2 :(得分:2)
我不会延长它,我会帮忙:
class MartinCursor {
private Cursor cursor;
MartinCursor(Cursor cursor) {
this.cursor = cursor;
}
String getString(String column) {
....
}
}
或
class MartinCursorHelper {
static String getString(Cursor cursor, String column) {
....
}
}
就个人而言,我会做后者,除非你讨厌一直提供这个额外的论点。
编辑:我忘了提到pydave的重点:如果你在循环中调用它,那么你就会对自己的性能产生明显的影响。首选方法是查找索引一次,缓存它,然后使用它。答案 3 :(得分:0)
你应该使用Android SDK中已经存在的DatabaseUtils .stringForQuery()静态方法来轻松检索一个值,这个例子适用于String
bot,还有{{1}的方法}}
Long
在db上运行查询并返回第一行第一列中的值的实用程序方法。
像
这样的东西stringForQuery(SQLiteDatabase db, String query, String[] selectionArgs)
答案 4 :(得分:0)
遇到这个寻找不同的解决方案,但只想添加这个,因为我相信答案是不能令人满意的。
您可以轻松创建自己的游标类。为了允许需要Cursor的函数接受它,它必须扩展AbstractCursor。要克服系统不使用您的类的问题,您只需将您的类作为包装器。
public class ExtendedCursor extends AbstractCursor {
/** The cursor to wrap. */
private final Cursor mCursor;
/** The name of the additional column. */
private final String mColumnName;
/** The value to be assigned to the additional column. */
private final Object mValue;
/**
* Creates a new cursor which extends the given cursor by adding a column with a constant value.
*
* @param cursor the cursor to extend
* @param columnName the name of the additional column
* @param value the value to be assigned to the additional column
*/
public ExtendedCursor(Cursor cursor, String columnName, Object value) {
mCursor = cursor;
mColumnName = columnName;
mValue = value;
}
@Override
public int getCount() {
return mCursor.getCount();
}
@Override
public String[] getColumnNames() {
String[] columnNames = mCursor.getColumnNames();
int length = columnNames.length;
String[] extendedColumnNames = new String[length + 1];
System.arraycopy(columnNames, 0, extendedColumnNames, 0, length);
extendedColumnNames[length] = mColumnName;
return extendedColumnNames;
}
这是它如何运作的一般概念。
现在问题的关键。要防止性能损失,请创建一个哈希来保存列索引。这将作为缓存。调用getString时,请检查列索引的哈希值。如果它不存在,则使用getColumnIndex获取它并缓存它。
对不起,我目前无法添加任何代码,但我在手机上,所以我稍后会尝试添加一些代码。