數(shù)據(jù)操作是指對(duì)數(shù)據(jù)的添加、刪除、查找和更新(CRUD)的操作。通過執(zhí)行SQL命名完成數(shù)據(jù)操作,但推薦使用Android提供的專用類和方法,這些類和方法更加簡潔、易用。
在上述實(shí)現(xiàn)了創(chuàng)建數(shù)據(jù)庫的DBAdapter類的基礎(chǔ)上,為了使DBAdapter類支持對(duì)數(shù)據(jù)的添加、刪除、更新和查找等功能,在DBAdapter類中增加下面的這些方法:
□ insert(People people)用來添加一條數(shù)據(jù)。
□ queryAllData()用來獲取全部數(shù)據(jù)。
□ queryOneData(long id)根據(jù)id獲取一條數(shù)據(jù)。
□ deleteAllData()用來刪除全部數(shù)據(jù)。
□ deleteOneData(long id)根據(jù)id刪除一條數(shù)據(jù)。
□ updateOneData(long id , People people)根據(jù)id更新一條數(shù)據(jù)。
代碼清單7-37 DBAdapter
public class DBAdapter {
public long insert(People people) {}
public long deleteAllData() { }
public long deleteOneData(long id) { }
public People[] queryAllData() {}
public People[] queryOneData(long id) { }
public long updateOneData(long id , People people){ }
private People[] ConvertToPeople(Cursor cursor){}
}
其中,ConvertToPeople(Cursor cursor)是私有方法,作用是將查詢結(jié)果轉(zhuǎn)換為用來存儲(chǔ)數(shù)據(jù)的自定義People類對(duì)象。
首先就來介紹一下自定義的People類。People類包含4個(gè)公共屬性,分別為ID、Name、Age和Height,對(duì)應(yīng)數(shù)據(jù)庫中的4個(gè)屬性值。覆蓋Object中的toString()方法,主要是為了便于界面顯示的需要。People類的代碼如代碼清單7-38所示。
代碼清單7-38 People類
public class People {
public int ID = -1;
public String Name;
public int Age;
public float Height;
@Override
public String toString(){
String result = "";
result += "ID:" + this.ID + ",";
result += "姓名:" + this.Name + ",";
result += "年齡:" + this.Age + ", ";
result += "身高:" + this.Height + ",";
return result;
}
}
下面分別介紹如何使用SQLiteDatabase類的公共方法,完成數(shù)據(jù)的添加、刪除、更新和查詢等數(shù)據(jù)操作。
SQLiteDatabase類的公共方法insert()、delete()、update()和query(),封裝了執(zhí)行的添加、刪除、更新和查詢功能的SQL命令。
1.添加功能
首先構(gòu)造一個(gè)ContentValues對(duì)象;其次調(diào)用ContentValues對(duì)象的put()方法,將每個(gè)屬性的值寫入ContentValues對(duì)象中;后使用SQLiteDatabase對(duì)象的insert()方法,將ContentValues對(duì)象中的數(shù)據(jù)寫入指定的數(shù)據(jù)庫表中。
insert()方法的返回值是新數(shù)據(jù)插入的位置,即ID值。ContentValues類是一個(gè)數(shù)據(jù)承載容器,主要用來向數(shù)據(jù)庫表中添加一條數(shù)據(jù)。
代碼清單7-39 insert
public long insert(People people) {
ContentValues newValues = new ContentValues();
newValues.put(KEY_NAME, people.Name);
newValues.put(KEY_AGE, people.Age);
newValues.put(KEY_HEIGHT, people.Height);
return db.insert(DB_TABLE, null, newValues);
}
在上述代碼中,第4行代碼向ContentValues對(duì)象newValues中添加一個(gè)名稱/值對(duì),put()方法的第1個(gè)參數(shù)是名稱,第2個(gè)參數(shù)是值;在第8行代碼的insert()方法中,第1個(gè)參數(shù)是數(shù)據(jù)表的名稱,第2個(gè)參數(shù)是在NULL時(shí)的替換數(shù)據(jù),第3個(gè)參數(shù)是需要向數(shù)據(jù)庫表中添加的數(shù)據(jù)。
2.刪除功能
刪除數(shù)據(jù)比較簡單,只需要調(diào)用當(dāng)前數(shù)據(jù)庫對(duì)象的delete()方法,并指明表名稱和刪除條件即可。
代碼清單7-40 刪除
public long deleteAllData() {
return db.delete(DB_TABLE, null, null);
}
public long deleteOneData(long id) {
return db.delete(DB_TABLE, KEY_ID + "=" + id, null);
}
其中,delete()方法的第1個(gè)參數(shù)是數(shù)據(jù)庫的表名稱,第2個(gè)參數(shù)是刪除條件。在第2行代碼中,刪除條件為null,表示刪除表中的所有數(shù)據(jù);第6行代碼指明了需要?jiǎng)h除數(shù)據(jù)的id值,因此deleteOneData()方法僅刪除一條數(shù)據(jù),此時(shí)delete()方法的返回值表示被刪除的數(shù)據(jù)的數(shù)量。
3.更新功能
更新數(shù)據(jù)同樣要使用ContentValues對(duì)象,首先構(gòu)造ContentValues對(duì)象,其次調(diào)用put()方法將屬性的值寫入ContentValues對(duì)象中,后使用SQLiteDatabase對(duì)象的update()方法,并指定數(shù)據(jù)的更新條件。
代碼清單7-41 更新
public long updateOneData(long id , People people){
ContentValues updateValues = new ContentValues();
updateValues.put(KEY_NAME, people.Name);
updateValues.put(KEY_AGE, people.Age);
updateValues.put(KEY_HEIGHT, people.Height);
return db.update(DB_TABLE, updateValues, KEY_ID + “=” + id, null);
}
在代碼的第7行中,update()方法的第1個(gè)參數(shù)表示數(shù)據(jù)表的名稱,第2個(gè)參數(shù)是更新條件,update()方法的返回值表示數(shù)據(jù)庫表中被更新的數(shù)據(jù)數(shù)量。
4.查詢功能
首先介紹Cursor類。在Android系統(tǒng)中,數(shù)據(jù)庫查詢結(jié)果的返回值并不是數(shù)據(jù)集合的完整復(fù)制,而是返回?cái)?shù)據(jù)集的指針,這個(gè)指針就是Cursor類。Cursor類支持在查詢的數(shù)據(jù)集合中多種移動(dòng)方式,并能夠獲取數(shù)據(jù)集合的屬性名稱和序號(hào)。
Cursor類的方法和說明如表7-8所示。
表7-8 Cursor類的方法和說明
方法 |
說明 |
moveToFirst |
將指針移動(dòng)到第一條數(shù)據(jù)上,返回boolean類型值,為true表示指針移動(dòng)成功 |
moveToNext |
將指針移動(dòng)到下一條數(shù)據(jù)上,返回boolean類型值,為true表示指針移動(dòng)成功 |
moveToPrevious |
將指針移動(dòng)到上一條數(shù)據(jù)上,返回boolean類型值,為true表示指針移動(dòng)成功 |
getCount |
獲取集合的數(shù)據(jù)數(shù)量 |
getColumnIndexOrThrow |
返回指定屬性名稱的序號(hào),如果屬性不存在則產(chǎn)生異常 |
getColumnName |
返回指定序號(hào)的屬性名稱 |
getColumnNames |
返回屬性名稱的字符串?dāng)?shù)組 |
getColumnIndex |
根據(jù)屬性名稱返回序號(hào) |
moveToPosition |
將指針移動(dòng)到指定的數(shù)據(jù)上,返回boolean類型值,為true表示指針移動(dòng)成功 |
getPosition |
返回當(dāng)前指針的位置 |
從Cursor中提取數(shù)據(jù)可以參考ConvertToPeople()方法的實(shí)現(xiàn)方法,具體代碼如代碼清單7-42所示。
代碼清單7-42 從Cursor中提取數(shù)據(jù)
private People[] ConvertToPeople(Cursor cursor){
int resultCounts = cursor.getCount();
if (resultCounts == 0 || !cursor.moveToFirst()){
return null;
}
People[] peoples = new People[resultCounts];
for (int i = 0 ; i<resultCounts; i++){
peoples[i] = new People();
peoples[i].ID = cursor.getInt(0);
peoples[i].Name=cursor.getString(cursor.getColumnIndex(KEY_NAME));
peoples[i].Age = cursor.getInt(cursor.getColumnIndex(KEY_AGE));
peoples[i].Height=cursor.getFloat(cursor.getColumnIndex(KEY_HEIGHT));
cursor.moveToNext();
}
return peoples;
}
在提取Cursor數(shù)據(jù)的數(shù)據(jù)前,推薦測試Cursor中的數(shù)據(jù)數(shù)量,避免在數(shù)據(jù)獲取中產(chǎn)生異常,例如,代碼的第3行到第5行。從Cursor中提取數(shù)據(jù)使用類型安全的get<Type>()方法,方法的輸入值為屬性的序號(hào),為了獲取屬性的序號(hào),可以使用getColumnIndex()方法獲取指定屬性的序號(hào),如代碼的第10行到第12行。
要進(jìn)行數(shù)據(jù)查詢就需要調(diào)用SQLiteDatabase類的query()方法,query()方法的語法如代碼清單7-43所示。
代碼清單7-43 query語法
Cursor android.database.sqlite.SQLiteDatabase.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
query()方法的參數(shù)說明如表7-9所示。
表7-9 query()方法的參數(shù)
位置 |
類型+名稱 |
說明 |
1 |
String table |
表名稱 |
2 |
String[] columns |
返回的屬性列名稱 |
3 |
String selection |
查詢條件 |
4 |
String[] selectionArgs |
如果在查詢條件中使用的問號(hào),則需要定義替換符的具體內(nèi)容 |
5 |
String groupBy |
分組方式 |
6 |
String having |
定義組的過濾器 |
7 |
String orderBy |
排序方式 |
根據(jù)id查詢數(shù)據(jù)的代碼如代碼清單7-44所示。
代碼清單7-44 根據(jù)id查詢數(shù)據(jù)的代碼
public People[] getOneData(long id) {
Cursor results = db.query(DB_TABLE, new String[] { KEY_ID, KEY_NAME, KEY_AGE, KEY_HEIGHT}, KEY_ID + "=" + id, null, null, null, null);
return ConvertToPeople(results);
}
查詢?nèi)繑?shù)據(jù)的代碼如代碼清單7-45所示。
代碼清單7-45 查詢?nèi)繑?shù)據(jù)的代碼
public People[] getAllData() {
Cursor results = db.query(DB_TABLE, new String[] { KEY_ID, KEY_NAME, KEY_AGE, KEY_HEIGHT}, null, null, null, null, null);
return ConvertToPeople(results);
}