在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而已。

下面是一个简单的例子,请先看效果图




android debug的包会混淆嘛 android debug database_应用



简单说明一下:

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中的一些基本的操作就是这样,大家如果还想了解得多一点,也可以自己在网上找资料。