SQLiteOpenHelper在query得到Cursor返回值异常问题探究

最近开发的一个功能会用到SQLite,碰到一个问题,纠结了整整一个下午,终于找到原因,记录一下。

      功能很简单,创建了一个自定义的ListView,在每个ListView中都对应有一个Button,而该Button需要有个状态记录Button使用情况,比如Enable和Disable。顺利地创建了数据库和自定义ListView,在点击Button时,将ListView对应的信息通过setTag(key, value)传递,并在Button的onClick()中通过getTag(key)获得对应属性。以上步骤暂时都未碰到任何问题,接下来问题就来了。

      在SQLiteOpenHelper的继承类DataBaseProvider中,增加了一个查询数据记录的函数,代码如下:

	public Cursor query(String name) {
		SQLiteDatabase db = this.getReadableDatabase();
		String querySql = "select " + PKG_NAME + " , " + CMP_STATE + " from " + TABLE_APPS_NAME + " where " + 
						CMP_NAME + " = '" + compName + "'";
		
		Cursor cursor = db.rawQuery(querySql, null);
		return cursor;
	}
在反复跟踪这段代码时,发现得到的Cursor对象值总有问题,数据内容老是对应的database中table的Column名,未得到正确的database record。百思不得其解,对应地也查找了Android工程中其他数据库查询的操作,也大同小异,最后检查下来才发现,在rawQuery结束后,需要将cursor定位到record的起始位置,即需要再调用一下cursor.moveToFirst()。最新代码更新如下:

	public Cursor query(String name) {
		SQLiteDatabase db = this.getReadableDatabase();
		String querySql = "select " + PKG_NAME + " , " + CMP_STATE + " from " + TABLE_APPS_NAME + " where " + 
						CMP_NAME + " = '" + compName + "'";
		
		Cursor cursor = db.rawQuery(querySql, null);
		cursor.moveToFirst();
		return cursor;
	}
到这里,数据库功能上的问题已经解决了,但是作为有专研精神的码农怎么能放过Discovery的好机会呢?那么我们从SQLiteDatabase的rawQuery接口开始分析,码农比较习惯以文件名来划分步骤:

1、SQLiteDatabase.java

    public Cursor rawQuery(String sql, String[] selectionArgs,
            CancellationSignal cancellationSignal) {
        return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal);
    }

显然,rawQuery(......)又调用了rawQueryWithFactory(......),函数如下:

    public Cursor rawQueryWithFactory(
            CursorFactory cursorFactory, String sql, String[] selectionArgs,
            String editTable, CancellationSignal cancellationSignal) {
        acquireReference();
        try {
            SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
                    cancellationSignal);
            return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
                    selectionArgs);
        } finally {
            releaseReference();
        }
    }
从代码看,是先创建了一个SQLiteDirectCursorDriver实例,并由该实例driver来执行query(...)。

2、SQLiteDirectCursorDriver.java

    public Cursor query(CursorFactory 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLiteOpenHelper是Android系统提供的一个用于管理SQLite数据库的帮助类,它封装了数据库的创建、升级和降级等操作。使用SQLiteOpenHelper可以方便地创建和管理SQLite数据库,避免了手动编写SQL语句的繁琐过程。 SQLiteOpenHelper类的使用步骤如下: 1. 自定义一个继承自SQLiteOpenHelper的帮助类,并实现onCreate()、onUpgrade()和onDowngrade()等方法。 2. 在自定义的帮助类中重写onCreate()方法,创建数据库和表格。 3. 在自定义的帮助类中重写onUpgrade()方法,升级数据库版本。 4. 在自定义的帮助类中重写onDowngrade()方法,降级数据库版本。 5. 在应用程序中创建自定义的帮助类对象,并调用getWritableDatabase()或getReadableDatabase()方法获取可读写的数据库对象。 示例代码: ```java public class MyDatabaseHelper extends SQLiteOpenHelper { public static final String CREATE_BOOK = "create table Book (" + "id integer primary key autoincrement, " + "author text, " + "price real, " + "pages integer, " + "name text)"; public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 升级数据库 } @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 降级数据库 } } ``` ```java MyDatabaseHelper dbHelper = new MyDatabaseHelper(context, "BookStore.db", null, 1); SQLiteDatabase db = dbHelper.getWritableDatabase(); // 获取可写数据库对象 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值