在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中的一些基本的操作就是这样,大家如果还想了解得多一点,也可以自己在网上找资料。
大家如果有兴趣,还可以再看一下前面关于Sharedpreference的应用的文章:
Android学习小Demo(7)SharedPreference的使用