編輯:關於Android編程
在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按鈕,更新數據,並刷新列表。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+NKOps6SwtMSzzPW8x8K8o6zJvrP9vMfCvKGjPC9wPgo8cD7PwsPmztLDx7+0v7RNYWluQWN0aXZpdHnW0LXEtPrC66Ost9ax8LbU06bT2rLlyOujrLj80MK6zcm+s/21xMfpv/ahozwvcD4KPHA+PHN0cm9uZz5JbnNlcnQ8L3N0cm9uZz48L3A+CjxwPjwvcD4KPHByZSBjbGFzcz0="brush:java;"> 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通過cursor來返回數據庫tasks表中的記錄,並將其放到一個List中,然後在Activity中給BaseAdapter綁定。queryAll(){ List list = new ArrayList (); 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; }
源代碼下載
關於SqliteDatabase中的一些基本的操作就是這樣,大家如果還想了解得多一點,也可以自己在網上找資料。
大家如果有興趣,還可以再看一下前面關於Sharedpreference的應用的文章:
Android學習小Demo(7)SharedPreference的使用
android 迭代開發中陸續遇到各種問題,我們要善於總結,歸類。現在記錄一下這幾個月遇到的問題匯總。1、android fragment中onActivityResul
廢話少說,直接上圖,有圖有真相。這兩個工具欄全是用布局來實現的。底部工具欄布局代碼:代碼復制代碼 代碼如下: < xmlns:android
android studio和eclipse 稍微有點不同。Android studio 版本1.3SqlCipher 版本3.3.11.將sqlcipher.jar復制
Binder概述一句話概括進程通信:進程間的數據傳遞。Binder是Anroid系統裡最重要的進程通信方式,很多文章會直接用代碼、原理類的文字進行描述,對於接觸Andro