Cursor遍历SQLite数据库出现多行null结果问题求助
首先看你的输出,说明数据库里确实存在image_title为null的行,数量和你启动应用插入数据的次数一致。结合你的代码,我发现几个关键问题:
1. updateLastTitle方法存在严重错误
这个方法里你犯了一个低级错误:用cursor.getColumnCount()来获取最后一行的_id值,但getColumnCount()返回的是查询结果的列数(这里你只查了_id一列,所以返回1),而不是当前行的_id数值。这会导致每次执行updateLastTitle时,你都在更新_id=1的行,而不是最后插入的那一行。
更糟的是,如果你的插入逻辑每次启动都执行,就会不断插入新的、image_title为null的行(比如调用了addEntry(byte[] image)这个重载),而你试图更新的始终是第一行,所以后面的行自然保留null的image_title。
修复updateLastTitle方法
建议用更安全的方式实现,避免字符串拼接(防止SQL注入),并且正确获取最后一行的_id:
public void updateLastTitle(String title) throws SQLiteException{ SQLiteDatabase database = this.getWritableDatabase(); // 先查询最后一行的_id,用ORDER BY + LIMIT更高效 Cursor cursor = database.rawQuery("SELECT "+ COLUMN_ID +" FROM " + DB_TABLE + " ORDER BY " + COLUMN_ID + " DESC LIMIT 1", null); if(cursor.moveToFirst()){ // 确保数据库中有数据再执行更新 long lastId = cursor.getLong(0); ContentValues cv = new ContentValues(); cv.put(KEY_NAME, title); // 使用update方法,安全且简洁 database.update(DB_TABLE, cv, COLUMN_ID + " = ?", new String[]{String.valueOf(lastId)}); } cursor.close(); }
2. 检查你的插入逻辑
你提到null的数量和启动应用插入数据的次数一致,说明每次启动应用时,你可能都调用了不带title参数的addEntry重载(比如addEntry(byte[] image)),这会直接插入image_title为null的行。请确认你的插入逻辑:只有在需要插入无标题的图片时才调用这些重载,而不是每次启动都执行插入操作。
3. 优化Cursor遍历代码
你的getAllTitledBitmap方法里的Cursor遍历可以更简洁可靠,不需要先调用moveToFirst(),直接用while(cursor.moveToNext())即可:
public List<TitledBitmap> getAllTitledBitmap() { SQLiteDatabase database = this.getReadableDatabase(); List<TitledBitmap> titledBitmaps = new ArrayList<TitledBitmap>(); Cursor cursor = database.query(DB_TABLE, new String[]{KEY_NAME, KEY_IMAGE}, null, null, null, null, null); while (cursor.moveToNext()) { // 直接遍历,空Cursor会自动跳过循环 String title = cursor.getString(0); System.out.println("This is the title : " + title); TitledBitmap titledBitmap = cursorToTitledBitmap(cursor); titledBitmaps.add(titledBitmap); } cursor.close(); return titledBitmaps; }
4. 可选:给列添加约束(如果需要)
如果你希望image_title不允许为null,可以修改表创建语句,给KEY_NAME添加NOT NULL约束:
private static final String CREATE_TABLE_IMAGE = "CREATE TABLE " + DB_TABLE + "("+ COLUMN_ID + " integer primary key autoincrement, " + KEY_NAME + " TEXT NOT NULL," + // 添加NOT NULL约束,强制标题不能为空 KEY_AUTHOR + " TEXT," + KEY_IMAGE + " BLOB);";
这样如果调用不带title的addEntry重载,插入操作会抛出异常,避免插入null标题的行。
内容的提问来源于stack exchange,提问作者Antoine Bon

