SQLite查询单条记录触发CursorIndexOutOfBoundsException问题求助
解决SQLite CursorIndexOutOfBoundsException的正确姿势
这个问题我太熟悉了!你遇到的java.lang.CursorIndexOutOfBoundsException: Index -1 requested本质原因有两个:
- SQLite Cursor的默认起始位置是索引-1,你直接调用
cursor.getLong(0)时,根本还没指向任何一条有效记录; - 你没有做数据存在性判断,如果表中ID=1的记录不存在(比如表是空的),同样会触发这个错误。
直接返回数组取get(0)确实是偷懒的做法,下面给你一套规范且健壮的实现方案:
核心修复点
- 必须先调用
cursor.moveToFirst()将Cursor移动到第一条记录,该方法会返回boolean值,true表示存在有效记录; - 用参数化查询代替直接拼接SQL(哪怕是固定ID,这也是防止SQL注入的最佳实践);
- 用列名获取索引代替硬编码数字索引,避免表结构变化导致的错误;
- 确保Cursor资源被正确关闭,避免内存泄漏;
- 处理没有找到记录的边界情况。
完整代码实现
public User_Token getUser_TokenDB() { User_Token auxUserToken = null; // 使用参数化查询,?是占位符 String sql = "SELECT * FROM " + TABLE_NAME_USER_TOKEN + " WHERE ID = ?"; Cursor cursor = this.database.rawQuery(sql, new String[]{"1"}); try { // 先移动到第一条记录,判断是否存在有效数据 if (cursor != null && cursor.moveToFirst()) { // 用getColumnIndexOrThrow获取列索引,比硬编码数字更健壮 auxUserToken = new User_Token( cursor.getLong(cursor.getColumnIndexOrThrow("ID")), cursor.getString(cursor.getColumnIndexOrThrow("token_column1")), // 替换成你的实际列名 cursor.getString(cursor.getColumnIndexOrThrow("token_column2")), cursor.getString(cursor.getColumnIndexOrThrow("token_column3")) ); } } catch (IllegalArgumentException e) { // 处理列名不存在的异常,方便排查表结构问题 e.printStackTrace(); } finally { // 确保Cursor被关闭,放在finally块里不管是否异常都会执行 if (cursor != null) { cursor.close(); } } return auxUserToken; }
使用说明
调用这个方法时,记得判断返回值是否为null,处理没有找到记录的情况:
User_Token userToken = getUser_TokenDB(); if (userToken != null) { // 正常处理数据 } else { // 没有找到ID=1的记录,做提示或其他逻辑 }
内容的提问来源于stack exchange,提问作者Nelson Silva
相关产品推荐
相关产品推荐

