Android数据储存之SQLite存储数据【一】

什么是 SQLiteDatabase? 
   一个 SQLiteDatabase 的实例代表了一个SQLite 的数据库,通过SQLiteDatabase 实例的一些方法,我们可以执行SQL 语句,对数据库进行增、删、查、改的操作。需要注意的是,数据库对于一个应用来说是私有的,并且在一个应用当中,数据库的名字也是惟一的。
什么是 SQLiteOpenHelper ?
   根据这名字,我们可以看出这个类是一个辅助类。这个类主要生成一个数据库,并对数据库的版本进行管理。当在程序当中调用这个类的方法getWritableDatabase(),或者getReadableDatabase()方法的时候,如果当时没有数据,那么Android 系统就会自动生成一 个数据库。SQLiteOpenHelper 是一个抽象类,我们通常需要继承它,并且实现里边的3 个函数
什么是 ContentValues 类?
     ContentValues 类和Hashmap/Hashtable 比较类似,它也是负责存储一些名值对,但是它存储的名值对当中的名是一个String 类型,而值都是基本类型。
什么是 Cursor ?
     Cursor 在Android 当中是一个非常有用的接口,通过Cursor 我们可以对从数据库查询出来的结果集进行随  机的读写访问。

SQLiteDatabase类介绍:

 SQLiteDatabase类为我们提供了很多种方法;对于添加、更新和删除来说,我们都可以使用

1 db.executeSQL(String sql);  

2 db.executeSQL(String sql, Object[] bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集 

除了统一的形式之外,他们还有各自的操作方法:

1 db.insert(String table, String nullColumnHack, ContentValues values);  

2 db.update(String table, Contentvalues values, String whereClause, String whereArgs);  

3 db.delete(String table, String whereClause, String whereArgs);

以上三个方法的第一个参数都是表示要操作的表名;insert中的第二个参数表示如果插入的数据每一列都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;insert中的第三个参数是ContentValues类型的变量,是键值对组成的Map,key代表列名,value代表该列要插入的值;update的第二个参数也很类似,只不过它是更新该字段key为最新的value值,第三个参数whereClause表示WHERE表达式,比如“age > ? and age < ?”等,最后的whereArgs参数是占位符的实际参数值;delete方法的参数也是一样

下面给出demo:

打开数据库
//db = SQLiteDatabase.openOrCreateDatabase("/data/data/com.hh.firstdemo/userTb.db", null);
db = this.openOrCreateDatabase("userTb.db", MODE_PRIVATE, null);
str_sql = "select count(*) as c from sqlite_master where type='table' and name='" + TABLE_NAME + "';";
cursor = db.rawQuery(str_sql, null);
if (cursor.moveToNext()) {
    int count = cursor.getInt(0);
    if (count < 1) {
        str_sql = "create table " + TABLE_NAME + " (id integer primary key,name text,age integer,gender text);";
        Log.d("sql", str_sql);
        db.execSQL(str_sql);
    }
}
cursor.close();
数据的添加
 String strName = txtName.getText().toString();
 Integer intAge = Integer.parseInt(txtAge.getText().toString());
 String strGender = txtGender.getText().toString();
1.使用insert方法
 ContentValues cv = new ContentValues();//实例化一个ContentValues用来装载待插入的数据
 cv.put("name", strName);//添加字段及内容
 cv.put("age", intAge);
 cv.put("gender", strGender);
 db.insert(TABLE_NAME, null, cv);//执行插入操作
2.使用execSQL方式来实现
 str_sql = "insert into " + TABLE_NAME + " (name,age,gender) values ('" + strName + "'," + intAge + ",'" + strGender + "');";
 db.execSQL(str_sql);//执行SQL语句
数据的删除
 String id = spinner.getSelectedItem().toString();
1.使用delete方法
 String whereClause = "id=?";//删除的条件
 String[] whereArgs = {id};//删除的条件参数
 db.delete(TABLE_NAME, whereClause, whereArgs);//执行删除
2.使用execSQL方式来实现
 str_sql = "delete from " + TABLE_NAME + " where id = " + id + ";";//删除操作的SQL语句
 db.execSQL(str_sql);//执行删除操作
 for (int i = 0; i < list.size(); i++) {
    if (list.get(i).equals(id)) {
        list.remove(i);
        adapter.notifyDataSetChanged();
    }
 }
数据修改
 String id = spinner.getSelectedItem().toString();
 String strName = txtName.getText().toString();
 Integer intAge = Integer.parseInt(txtAge.getText().toString());
 String strGender = txtGender.getText().toString();
1.使用update方法
 ContentValues cv = new ContentValues();//实例化ContentValues
 cv.put("name", strName);//添加要更改的字段及内容
 cv.put("age", intAge);
 cv.put("gender", strGender);
 String whereChsuse = "id=?";//修改条件
 String[] whereArgs = {id};//修改条件的参数
 db.update(TABLE_NAME, cv, whereChsuse, whereArgs);//执行修改
2.使用execSQL方式来实现
 str_sql = "update " + TABLE_NAME + " set name='" + strName + "',"
 +"age=" + intAge + ",gender='" + strGender + "' "
 +"where id =" + id + ";";//修改的SQL语句
 db.execSQL(str_sql);//执行修改

数据查询 

面来说说查询操作。查询操作相对于上面的几种操作要复杂些,因为我们经常要面对着各种各样的查询条件,所以系统也考虑到这种复杂性,为我们提供了较为丰富的查询形式:

db.rawQuery(String sql, String[] selectionArgs);  

db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy);  

db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);  

db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);

上面几种都是常用的查询方法,第一种最为简单,将所有的SQL语句都组织到一个字符串中,使用占位符代替实际参数,selectionArgs就是占位符实际参数集;

各参数说明:

table:表名称

colums:表示要查询的列所有名称集

selection:表示WHERE之后的条件语句,可以使用占位符

selectionArgs:条件语句的参数数组

groupBy:指定分组的列名

having:指定分组条件,配合groupBy使用

orderBy:y指定排序的列名

limit:指定分页参数

distinct:指定“true”或“false”表示要不要过滤重复值

Cursor:返回值,相当于结果集ResultSet

最后,他们同时返回一个Cursor对象,代表数据集的游标,有点类似于JavaSE中的ResultSet。下面是Cursor对象的常用方法:

c.move(int offset); //以当前位置为参考,移动到指定行  

c.moveToFirst();    //移动到第一行  

c.moveToLast();     //移动到最后一行  

c.moveToPosition(int position); //移动到指定行  

c.moveToPrevious(); //移动到前一行  

c.moveToNext();     //移动到下一行  

c.isFirst();        //是否指向第一条  

c.isLast();     //是否指向最后一条  

c.isBeforeFirst();  //是否指向第一条之前  

c.isAfterLast();    //是否指向最后一条之后  

c.isNull(int columnIndex);  //指定列是否为空(列基数为0)  

c.isClosed();       //游标是否已关闭  

c.getCount();       //总数据项数  

c.getPosition();    //返回当前游标所指向的行数  

c.getColumnIndex(String columnName);//返回某列名对应的列索引值  

c.getString(int columnIndex);   //返回当前行指定列的值

 实现代码

String[] params =  {12345,123456};

Cursor cursor = db.query("user",columns,"ID=?",params,null,null,null);//查询并获得游标

if(cursor.moveToFirst()){//判断游标是否为空

    for(int i=0;i<cursor.getCount();i++){

        cursor.move(i);//移动到指定记录

        String username = cursor.getString(cursor.getColumnIndex("username");

        String password = cursor.getString(cursor.getColumnIndex("password"));

    }

}

通过rawQuery实现的带参数查询

Cursor result=db.rawQuery("SELECT ID, name, inventory FROM mytable");

//Cursor c = db.rawQuery("s name, inventory FROM mytable where ID=?",new Stirng[]{"123456"});    

result.moveToFirst(); 

while (!result.isAfterLast()) { 

    int id=result.getInt(0); 

    String name=result.getString(1); 

    int inventory=result.getInt(2); 

    // do something useful with these 

    result.moveToNext(); 

 } 

 result.close();

在上面的代码示例中,已经用到了这几个常用方法中的一些,关于更多的信息,大家可以参考官方文档中的说明。

最后当我们完成了对数据库的操作后,记得调用SQLiteDatabase的close()方法释放数据库连接,否则容易出现SQLiteException。

上面就是SQLite的基本应用,但在实际开发中,为了能够更好的管理和维护数据库,我们会封装一个继承自SQLiteOpenHelper类的数据库操作类,然后以这个类为基础,再封装我们的业务逻辑方法。

相关推荐