Android在使用sqlite数据库时游标的move方法的一些误解

       前几天在写一个小项目的时候,使用到了Android的sqlite数据库,有关于sqlite数据库的使用方法,大家可以百度,这里就不不再赘述。当我从数据库中取出数据后,用for循环遍历游标的时候,程序闪!退!了!!,我的老天鹅!for循环竟然出错了,赶紧看了一下错误日志,发现是在游标中取数据的时候超出了游标的界限,也就是说所取的位置超出了游标中的总数,但是使用moveToNext没有问题!这就很奇怪了,在这里先不卖关子,经过我的猜测和百度以及官方文档,最终知道了问题的出处,就是游标的move方法,cursor.move()方法是根据当前位置移动的数量,而不是从第一条移动到指定位置。下图是官方说明:

 

(从当前位置移动光标相对大小,向前或向后移动。)之前一直以为是后者。

 

什么意思呢,怎么证明呢,爬坑之旅开始,首先Android项目,创建数据库辅助类DataBaseHelper并且继承SQLiteOpenHelper,在初次加载程序时创建test测试表,并且插入10条数据,10条数据从0到9,该表中只有一个字段:

package com.example.sqlite;


import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;


public class DataBaseHelper extends SQLiteOpenHelper {


/**
 * @param context
 *            上下文
 * @param name
 *            数据库名字
 * @param factory
 *            游标,当我们传入null时代表使用系统自带的CursorFactory
 * @param version
 *            版本
 */
Context context;


public DataBaseHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
this.context = context;
}


/**
 * 在首次加载程序时,创建所需要的表
 */
@Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
try {
arg0.execSQL("create table test (num varchar(20))");
arg0.execSQL("insert into test values ('0')");
arg0.execSQL("insert into test values ('1')");
arg0.execSQL("insert into test values ('2')");
arg0.execSQL("insert into test values ('3')");
arg0.execSQL("insert into test values ('4')");
arg0.execSQL("insert into test values ('5')");
arg0.execSQL("insert into test values ('6')");
arg0.execSQL("insert into test values ('7')");
arg0.execSQL("insert into test values ('8')");
arg0.execSQL("insert into test values ('9')");


} catch (Exception e) {
// TODO: handle exception
Toast.makeText(context, "数据库创建失败" + e, 1).show();
}


}


@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub


}


}

 

 

然后在activity中放置一个button按钮,用于点击它获取数据

 

然后在点击事件中获取数据库中的值并且从小到大排序,然后使用for循环将i和对应取出来的数字打印出来

SQLiteDatabase sqLiteDatabase = dataBaseHelper
.getReadableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery("select * from test order by num",
null);
cursor.moveToFirst();
for (int i = 0; i < cursor.getCount(); i++) {
Log.e("i", i + "");
cursor.move(i);
Log.e("num", cursor.getString(0));
}

好,开始运行程序,你会发现程序闪退了,这个时候看打印的log日志,

 

当i等于0的时候,取得是0,当i等于1的时候,取得值是1,到现在好像还没出现什么问题,但是再接着往下看,当i等于2的时候,取得值是3!什么,3不应该是在第四个位置吗,也就是应该当i等于4的时候,再往下看,当i真正的等于4的时候,会发现,程序异常了,常了,了……,查看错误信息报CursorIndexOutOfBoundsException异常,超出了CursorI的大小。

这个时候我们在来分析一下上面打印的log日志,当一、(i=0,num=0),二(i=1,num=1),三、(i=2,num=3),四、(i=3,num=5),有没有发现规律,那就是本次的num加下一次i等于下一次的num,即一里面的num加二里面的i等于二里面的num,以此类推,由此便可证明move是根据当前位置向前或者向后移动指定位数。

 

好了,当然我当时没有来得及查看文档,使用的是moveToNext()方法,个人推荐使用此方法,省事方便安全,当然如果这篇文章有什么错误之处,还请指正,谢谢。多学习,多总结。

                                                                                                                                转载请注明出处啊,谢谢

加入我的行列:

(嘿嘿嘿,点击这里关于我哦,分享小知识):https://www.jianshu.com/p/7d19f0df5b6b

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值