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类的数据库操作类,然后以这个类为基础,再封装我们的业务逻辑方法。