在Android中,除了我们之前说过的sharedpreference可以用来保存数据之外,SQLiteDatabase应该是使用得最广泛的一种数据保存方式。
SQLite是一个嵌入式的数据库,支持一般数据库的增删查改,如果大家对数据库有一定的了解的话,会发现,其实这也是很简单的一种使用方式。
今天我们就来看一下在Android中,SQLiteDatabase的实际应用。
在Android中,sqlite的基本操作差不多就是下面几种,我们可以直接用Activity中用以下的操作语句。
SQLiteDatabase database = openOrCreateDatabase("database_name", MODE_PRIVATE, null);
database.execSQL(sql);
database.insert(table, nullColumnHack, values);
database.update(table, values, whereClause, whereArgs);
database.delete(table, whereClause, whereArgs);
database.rawQuery(sql, selectionArgs);
database.query(distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit, cancellationSignal);
但是一般来说,不会直接这么在Activity中这么用,因为会将数据库方面的操作跟业务中逻辑都搞在一起了,其实在Web应用,我们也是将其分开的,会有Factory,DAO,Model等层次来分开。在Android中,一般会分成两个类来用:
1)一个继承自SQLiteOpenHelper的自定义类,假设就叫做DatabaseHelper吧。
public class DatabaseHelper extends SQLiteOpenHelper{
private static final String DB_NAME = "ToDo.db";
public static final String TABLE_NAME = "tasks";
private static final String SQL_CREATE_TABLE = "create table if not exists " + TABLE_NAME
+ " ( _id integer primary key autoincrement, "
+ " title varchar(30),"
+ " content varchar(200), "
+ " flagCompleted char(1) "
+ " )";
private static final int DATABASE_VERSION = 1;
public DatabaseHelper(Context context){
super(context, DB_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//Firsttime you don't need to anything
}
}
在这个类中,我们要实现三个函数:
1.1)构造函数,要调用父类的构造函数,将数据库名和版本(DB_NAME和VERSION)传进去,构造我们的Database。
1.2)OnCreate函数,这是数据库被创建的时候调用的函数,可以在这里做一些初始化的工作,比如创建表等,也可以不做。
1.3)OnUpgrade函数,这个函数是我们升级数据库时候用到的,举个例子,第一次发布的时候,我们数据库版本是1,表里面只有一个字段,第二次发布的时候,数据库的版本设置成2,那么Android系统检测到数据库的版本变化了,那么它就会调用onUpgrade函数,我们就可以在onUpgrade函数中实现我们想改变的逻辑,比如在原来的表增加字段之类的。
2)第二个类,也是我们自定义的一个类,用来包装数据库的insert(增),update(改),delete(删),query(查)等操作,如下:
2.1)构造自定义函数,通过上面定义的DatabaseHelper获得一个SQliteDatabase的对象。
private SQLiteDatabase database;
public DatabaseManager(Context context){
DatabaseHelper databaseHelper = new DatabaseHelper(context);
database = databaseHelper.getWritableDatabase();
}
2.2)然后根据这个database对象,我们可以定义几个函数,分别实现增删查改等功能。
public boolean insert(Object[] values){
database.execSQL(SQL_INSERT,values);
return true;
}
public boolean insert(ContentValues contentValues){
database.insert(TABLE_NAME, null, contentValues);
return true;
}
public boolean update(ContentValues contentValues, String whereClause, String[] whereArgs){
database.update(TABLE_NAME, contentValues, whereClause, whereArgs);
return true;
}
public boolean delete(String whereClause, String[] whereArgs){
database.delete(TABLE_NAME, whereClause, whereArgs);
return true;
}
2.2.1)可以自己写SQL语句,然后通过database.execSQL(SQL, Object[] values)来运行SQL,如上面的第一个insert函数,其中SQL_INSERT如下:
private static final String SQL_INSERT = "insert into " + TABLE_NAME + " values (NULL, ?, ?, ?)";
也可以通过contentvalues,调用SQLiteDatabase提供的insert函数:
database.insert(table, nullColumnHack, values);
2.2.2)Update函数,需要传进去where语句来过滤条件,后面的whereArgs是where语句里面的参数值。
2.2.3)Delete函数,跟Update函数一样,只是不需要利用contentValues来更新records而已。
下面是一个简单的例子,请先看效果图
简单说明一下:
1)页面上是一个ListView,用来展现数据,左边是一个CheckBox,旁边是一个TextView。
2)点击Insert按钮,添加一条数据,并刷新列表。
3)选中记录,点击Update按钮,更新数据,并刷新列表。
4)长按某条记录,删除记录。
下面我们看看MainActivity中的代码,分别对应于插入,更新和删除的情况。
Insert
private boolean insert(){
//Using SQL to insert data
// database.execSQL(SQL_INSERT, new Object[] {task.getTitle(), task.getContent()});
//Using ContentValues to insert data
ContentValues contentValues = new ContentValues();
contentValues.put("title","TestTask");
contentValues.put("content", "I'm going to introduce SQLiteDatabase");
contentValues.put("flagCompleted","N");
return dbManager.insert(contentValues);
}
Update
因为update的时候,需要知道到底有哪些记录是选中的,所以定义了一个list来存放选中的记录。
OnItemClickListener onItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
viewHolder.cbCompleted.toggle();
String taskId = String.valueOf(id);
if(viewHolder.cbCompleted.isChecked()){
if(!selectedTasks.contains(taskId)){
selectedTasks.add(taskId);
}
}else{
if(selectedTasks.contains(taskId)){
selectedTasks.remove(taskId);
}
}
}
};
private boolean update(){
if(selectedTasks.size() > 0){
for(String taskId : selectedTasks){
Log.v(TAG, "taskId = " + taskId);
ContentValues contentValues = new ContentValues();
contentValues.put("title","Update Task");
dbManager.update(contentValues, "_id = ? ", new String[] {taskId});
}
return true;
}else{
Toast.makeText(this, "No selected items!", Toast.LENGTH_SHORT).show();;
return false;
}
}
Delete
OnItemLongClickListener onItemLongClickListener = new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
if(dbManager.delete("_id = ? ", new String[] {String.valueOf(id)})){
tasks = dbManager.queryAll();
taskAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity.this, "Delete Successfully", Toast.LENGTH_SHORT).show();
}
return false;
}
};
差点忘了,还有一个查询的功能呢。
在DatabaseManager中,我们也定义了如下的查询功能:
public List<Task> queryAll(){
List<Task> list = new ArrayList<Task>();
Cursor cursor = database.rawQuery(SQL_QUERY, null);
if(cursor == null){
}else if(!cursor.moveToFirst()){
}else{
int columnId = cursor.getColumnIndex("_id");
int columnTitle = cursor.getColumnIndex("title");
int columnContent = cursor.getColumnIndex("content");
int columnFlagCompleted = cursor.getColumnIndex("flagCompleted");
do{
int id = cursor.getInt(columnId);
String title = cursor.getString(columnTitle);
String content = cursor.getString(columnContent);
String flagCompleted = cursor.getString(columnFlagCompleted);
Task task = new Task();
task.setId(id);
task.setTitle(title);
task.setContent(content);
task.setFlagCompleted(flagCompleted);
list.add(task);
}while(cursor.moveToNext());
}
cursor.close();
Log.v(TAG, "Total Records : " + list.size());
return list;
}
通过cursor来返回数据库tasks表中的记录,并将其放到一个List中,然后在Activity中给BaseAdapter绑定。
源代码下载
关于SqliteDatabase中的一些基本的操作就是这样,大家如果还想了解得多一点,也可以自己在网上找资料。