数据存储之 SQLite 数据库操作(三)
生活随笔
收集整理的這篇文章主要介紹了
数据存储之 SQLite 数据库操作(三)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上一講中我們講到了SQLite數據庫的操作方法 [數據存儲之SQLite數據庫操作(二)],我們主要是以SQL語句對數據庫進行增刪改查,這一講我們來學習一下 Android 建議的對數據庫的操作方法
??? 查看 SQLiteDatabase 中, 在上一講中有講到 execSQL (String sql, Object[] bindArgs) 這個方法,在這里Android建議我們在操縱數據庫的時候用以下幾種方式: 1) 插入: insert(String, String, ContentValues) insertOrThrow(String, String, ContentValues) insertWithOnConflict(String, String, ContentValues, int)
2) 更新: update(String, ContentValues, String, String[]) updateWithOnConflict(String, ContentValues, String, String[], int)
3) 刪除: delete(String, String, String[])
[注]這一講中我們就來使用Android推薦的這些操作數據庫的方法來進行數據庫的操作,Demo 還是與上一講類似,讀者可以結合上一講內容來學習,對比之間的不同。
????public long insert (String table, String nullColumnHack, ContentValues values)
??? 插入一行數據到數據庫中 參數: table :?需要插入行的表的名稱 nullColumnHack :?這個參數是可選的,可以為null, SQL 不允許插入一個至少一列都不命名的完全空的行。如果你提供的 values 是空的,而且
沒有已知的的列名,這就是一個空行,這是不能被插入的。如果設置非空,nullColumnHack 參數提供一個可為空的列的名稱,當插入的 values 是空的時候,就將這個列名置為NULL,然后values值插入。 values :?指定行對應的列的值,這個類型很類似Map,key表示列的名稱,values表示列的值 返回值: 返回新插入的行的ID,如果存在錯誤默認返回 -1 [備注]第二個參數翻譯的有些拘謹,我們可以這樣理解
當在沒有任何已知的列名的情況下,values參數為空的時候,insert是會失敗的(數據庫不允許插入一個空行),為了防止Insert()方法要求必須添加一條除了主鍵之外其它字段為Null值的記錄,我們要在這里必須指定一個列名[因為values值是以ContentValues 的形式來存儲的],到時候如果發現將要插入的行為空行時,就會將你指定的這個列名的值設為null,然后再將values值向NULL列中插入。查看源代碼,我們可以發現 Android 中操作數據庫的方法底層也是通過構造SQL語句來實現的。 2)?查看API文檔SQLiteDatabase 中的
public int delete (String table, String whereClause, String[] whereArgs)
刪除操作?
參數: table :?表示表名 whereClause :?可選項,是可以通過 SQL語句中where語句來過濾條件刪除的條目,如果是null 表示刪除所有行 whereArgs :?緊跟第二個參數,作為刪除過濾條件的占位符,詳情請看下面程序 PersonDao2 的 deletePerson() 方法的操作。 返回值: 如果是 0 表示未刪除任何行,如果已經有刪除行的操作 會得到 count > 0的數,表示刪除的行數
更新操作
參數: distinct :??判斷是否返回的行是唯一值,如果想要返回唯一的行,則為true,否則為false。 table :需要查詢的表的名稱。 columns :需要返回的列,如果要返回所有列則置為null。 selection :過濾需要返回的行,格式遵從SQL中 SQL WHERE 語句(除了Where關鍵字以外).如果返回給定表的所有行,則置為Null。 selectionArgs :?過濾條件的占位符,這里的值會代替過濾語句中 "?"。 groupBy :?過濾條件對行進行分組,格式遵從SQL中 SQL GROUP BY 語句 (除了關鍵字GROUP BY之外),如果不分組,置為Null。 having :?對分組過濾條件的占位符操作。 orderBy :?如何進行排序,遵從SQL中的SQL ORDER BY 語句, 如果是null表示使用默認的排序順序。 limit :是否對數據庫進行分頁的查詢。 返回值:
它返回的是一個游標,這個用法之前有講過,不懂的可以查看前面幾講內容的介紹
package?com.android.sqlitedemo.db;?? ?? import?android.content.Context;?? import?android.database.sqlite.SQLiteDatabase;?? import?android.database.sqlite.SQLiteOpenHelper;?? ?? public?class?DBOpenHelper?extends?SQLiteOpenHelper?{?? ?? ????private?static?String?name?=?"mydb.db";?//?表示數據庫的名稱?? ????private?static?int?version?=?1;?//?表示數據庫的版本號?? ?? ????public?DBOpenHelper(Context?context)?{?? ????????super(context,?name,?null,?version);?? ????????//?TODO?Auto-generated?constructor?stub?? ????}?? ?? ????//?當數據庫創建的時候,是第一次被執行,完成對數據庫的表的創建?? ????@Override?? ????public?void?onCreate(SQLiteDatabase?db)?{?? ????????//?TODO?Auto-generated?method?stub?? ????????//?SQLite?數據創建支持的數據類型:?整型數據,字符串類型,日期類型,二進制的數據類型?? ????????//?數據庫這邊有一個特點,就是SQLite數據庫中文本類型沒有過多的約束,也就是可以把布爾類型的數據存儲到文本類型中,這樣也是可以的?? ????????String?sql?=?"create?table?person(id?integer?primary?key?autoincrement,name?varchar(64),address?varchar(64),sex?varchar(8))";?? ????????db.execSQL(sql);?//?完成數據庫的創建?? ????}?? ?? ????@Override?? ????public?void?onUpgrade(SQLiteDatabase?db,?int?oldVersion,?int?newVersion)?{?? ????????//?TODO?Auto-generated?method?stub?? ????}?? ?? }?? 3) PersonService2.java 定義操作數據庫(增刪改查)的接口 [java]?view plaincopy package?com.android.sqlitedemo.service;?? ?? import?android.content.ContentValues;?? ?? import?java.util.List;?? import?java.util.Map;?? ?? ?? /**? ?*?定義好增刪改查接口? ?*?@author?xukunhui? ?*? ?*/?? public?interface?PersonService2?{?? ?? ????public?boolean?addPersion(ContentValues?values);??? ?????? ????public?boolean?deletePerson(String?whereClause,?String[]?whereArgs);?? ?????? ????public?boolean?updatePerson(ContentValues?values,?String?whereClause,?String[]?whereArgs);?? ?????? ????//使用?Map<String,?String>?做一個封裝,比如說查詢數據庫的時候返回的單條記錄?? ????public?Map<String,?String>?viewPerson(String?selection,?String[]?selectionArgs);?? ?????? ????//使用?List<Map<String,?String>>?做一個封裝,比如說查詢數據庫的時候返回的多條記錄?? ????public?List<Map<String,?String>>?listPersonMaps(String?selection,?String[]?selectionArgs);?? }?? 3) PersonDao2.java 實現操作數據庫的增刪改查的功能 [java]?view plaincopy package?com.android.sqlitedemo.dao;?? ?? import?android.content.ContentValues;?? import?android.content.Context;?? import?android.database.Cursor;?? import?android.database.sqlite.SQLiteDatabase;?? ?? import?com.android.sqlitedemo.db.DBOpenHelper;?? import?com.android.sqlitedemo.service.PersonService2;?? ?? import?java.util.ArrayList;?? import?java.util.HashMap;?? import?java.util.List;?? import?java.util.Map;?? ?? public?class?PersonDao2?implements?PersonService2?{?? ?? ????private?DBOpenHelper?helper?=?null;?? ?? ????public?PersonDao2(Context?context)?{?? ????????helper?=?new?DBOpenHelper(context);?? ????}?? ?? ????@Override?? ????public?boolean?addPersion(ContentValues?values)?{?? ????????//?TODO?Auto-generated?method?stub?? ????????boolean?flag?=?false;?? ????????SQLiteDatabase?database?=?null;?? ????????long?id?=?-1;?? ????????try?{?? ????????????database?=?helper.getWritableDatabase();?? ????????????id?=?database.insert("person",?null,?values);?? ????????????flag?=?(id?!=?-1???true?:?false);?? ????????}?catch?(Exception?e)?{?? ????????????//?TODO:?handle?exception?? ????????}?finally?{?? ????????????if?(database?!=?null)?{?? ????????????????database.close();?? ????????????}?? ????????}?? ????????return?flag;?? ????}?? ?? ????@Override?? ????public?boolean?deletePerson(String?whereClause,?String[]?whereArgs)?{?? ????????//?TODO?Auto-generated?method?stub?? ????????boolean?flag?=?false;?? ????????SQLiteDatabase?database?=?null;?? ????????int?count?=?0;?? ????????try?{?? ????????????database?=?helper.getWritableDatabase();?? ????????????count?=?database.delete("person",?whereClause,?whereArgs);?? ????????????flag?=?(count?>?0???true?:?false);?? ????????}?catch?(Exception?e)?{?? ????????????//?TODO:?handle?exception?? ????????}?finally?{?? ????????????if?(database?!=?null)?{?? ????????????????database.close();?? ????????????}?? ????????}?? ????????return?flag;?? ????}?? ?? ????@Override?? ????public?boolean?updatePerson(ContentValues?values,?String?whereClause,?String[]?whereArgs)?{?? ????????//?TODO?Auto-generated?method?stub?? ????????boolean?flag?=?false;?? ????????SQLiteDatabase?database?=?null;?? ????????int?count?=?0;?//?影響數據庫的行數?? ????????try?{?? ????????????database?=?helper.getWritableDatabase();?? ????????????count?=?database.update("person",?values,?whereClause,?whereArgs);?? ????????????flag?=?(count?>?0???true?:?false);?? ????????}?catch?(Exception?e)?{?? ????????????//?TODO:?handle?exception?? ????????}?finally?{?? ????????????if?(database?!=?null)?{?? ????????????????database.close();?? ????????????}?? ????????}?? ????????return?flag;?? ????}?? ?? ????//?查詢單條記錄?? ????@Override?? ????public?Map<String,?String>?viewPerson(String?selection,?String[]?selectionArgs)?{?? ????????//?TODO?Auto-generated?method?stub?? ????????//?select?*?from?? ????????//?*?表示?返回的列的名稱(投影查詢)?from?? ????????SQLiteDatabase?database?=?null;?? ????????Cursor?cursor?=?null;?? ????????Map<String,?String>?map?=?new?HashMap<String,?String>();?? ????????try?{?? ????????????database?=?helper.getReadableDatabase();?? ????????????cursor?=?database.query(true,?"person",?null,?selection,?selectionArgs,?null,?? ????????????????????null,?null,?null);?//查詢單條記錄,記錄是唯一的,所以第一個參數置為?true.?? ????????????int?cols_len?=?cursor.getColumnCount();?//?獲取游標個數,即查詢所得的結果數目?? ????????????while?(cursor.moveToNext())?{?? ????????????????for?(int?i?=?0;?i?<?cols_len;?i++)?{?? ????????????????????String?cols_name?=?cursor.getColumnName(i);?? ????????????????????String?cols_values?=?cursor.getString(cursor.getColumnIndex(cols_name));?? ????????????????????if?(cols_values?==?null)?{?? ????????????????????????cols_values?=?"";?? ????????????????????}?? ????????????????????map.put(cols_name,?cols_values);?? ????????????????}?? ????????????}?? ????????}?catch?(Exception?e)?{?? ????????????//?TODO:?handle?exception?? ????????????e.printStackTrace();?? ????????}?finally?{?? ????????????if?(database?!=?null)?{?? ????????????????database.close();?? ????????????}?? ????????}?? ????????return?map;?? ????}?? ?? ????//?查詢多條記錄?? ????@Override?? ????public?List<Map<String,?String>>?listPersonMaps(String?selection,?String[]?selectionArgs)?{?? ????????//?TODO?Auto-generated?method?stub?? ????????SQLiteDatabase?database?=?null;?? ????????Cursor?cursor?=?null;?? ????????List<Map<String,?String>>?list?=?new?ArrayList<Map<String,String>>();?? ????????try?{?? ????????????database?=?helper.getReadableDatabase();?? ????????????cursor?=?database.query(false,?"person",?null,?selection,?selectionArgs,?null,?? ????????????????????null,?null,?null);?//查詢所有記錄,所以有重復的數據也要全部檢出,所以第一參數置為false.?? ????????????int?cols_len?=?cursor.getColumnCount();?? ????????????while?(cursor.moveToNext())?{?? ????????????????Map<String,?String>?map?=?new?HashMap<String,?String>();?? ????????????????for?(int?i?=?0;?i?<?cols_len;?i++)?{?? ????????????????????String?cols_name?=?cursor.getColumnName(i);?? ????????????????????String?cols_values?=?cursor.getString(cursor.getColumnIndex(cols_name));?? ????????????????????if?(cols_values?==?null)?{?? ????????????????????????cols_values?=?"";?? ????????????????????}?? ????????????????????map.put(cols_name,?cols_values);?? ????????????????}?? ????????????????list.add(map);?? ????????????}?? ????????}?catch?(Exception?e)?{?? ????????????//?TODO:?handle?exception?? ????????????e.printStackTrace();?? ????????}?finally?{?? ????????????if?(database?!=?null)?{?? ????????????????database.close();?? ????????????}?? ????????}?? ????????return?list;?? ????}?? }?? 4) MainActivity.java 點擊按鈕觸發操作數據的事件 [java]?view plaincopy package?com.android.sqlitedemo;?? ?? import?java.util.List;?? import?java.util.Map;?? ?? import?com.android.sqlitedemo.dao.PersonDao2;?? import?com.android.sqlitedemo.db.DBOpenHelper;?? import?com.android.sqlitedemo.service.PersonService2;?? ?? import?android.os.Bundle;?? import?android.app.Activity;?? import?android.content.ContentValues;?? import?android.util.Log;?? import?android.view.Menu;?? import?android.view.View;?? import?android.view.View.OnClickListener;?? import?android.widget.Button;?? ?? public?class?MainActivity?extends?Activity?{?? ?? ????private?Button?button1;?? ????private?Button?button2;?? ????private?Button?button3;?? ????private?Button?button4;?? ????private?Button?button5;?? ????private?Button?button6;?? ?? ????private?static?final?String?TAG?=?"MainActivity";?? ?? ????@Override?? ????protected?void?onCreate(Bundle?savedInstanceState)?{?? ????????super.onCreate(savedInstanceState);?? ????????setContentView(R.layout.activity_main);?? ????????initComponent();?? ????????button1.setOnClickListener(new?OnClickListener()?{?? ?? ????????????@Override?? ????????????public?void?onClick(View?v)?{?? ????????????????//?TODO?Auto-generated?method?stub?? ????????????????DBOpenHelper?helper?=?new?DBOpenHelper(MainActivity.this);?? ????????????????//?調用?getWritableDatabase()或者?getReadableDatabase()其中一個方法將數據庫建立?? ????????????????helper.getWritableDatabase();?? ????????????}?? ????????});?? ????????button2.setOnClickListener(new?OnClickListener()?{?? ?? ????????????@Override?? ????????????public?void?onClick(View?v)?{?? ????????????????//?TODO?Auto-generated?method?stub?? ????????????????PersonService2?service2?=?new?PersonDao2(MainActivity.this);?? ????????????????ContentValues?values?=?new?ContentValues();?? ????????????????values.put("name",?"AHuier");?? ????????????????values.put("address",?"XIAMEN");?? ????????????????values.put("sex",?"male");?? ????????????????boolean?flag?=?service2.addPersion(values);?? ????????????????Log.i(TAG,?"----?addPersion?--->"?+?flag);?? ????????????}?? ????????});?? ????????button3.setOnClickListener(new?OnClickListener()?{?? ????????????@Override?? ????????????public?void?onClick(View?v)?{?? ????????????????PersonService2?service2?=?new?PersonDao2(MainActivity.this);?? ????????????????//?刪除的SQL語句?:delete?from?person?where?id?=???? ????????????????//?不包含?where?關鍵字?? ????????????????boolean?flag?=?service2.deletePerson("?id?=???",?new?String[]?{?? ????????????????????"4"?? ????????????????});?? ????????????????Log.i(TAG,?"----?deletePerson?---->"?+?flag);?? ????????????}?? ????????});?? ????????button4.setOnClickListener(new?OnClickListener()?{?? ?? ????????????@Override?? ????????????public?void?onClick(View?v)?{?? ????????????????//?TODO?Auto-generated?method?stub?? ????????????????PersonService2?service2?=?new?PersonDao2(MainActivity.this);?? ????????????????ContentValues?values?=?new?ContentValues();?? ????????????????values.put("name",?"AHuier");?? ????????????????values.put("address",?"XIAMEN");?? ????????????????values.put("sex",?"female");?? ????????????????boolean?flag?=?service2.updatePerson(values,?"?id?=???",?new?String[]?{?? ????????????????????"1"?? ????????????????});?? ????????????????Log.i(TAG,?"----?updatePerson?--->"?+?flag);?? ????????????}?? ????????});?? ????????button5.setOnClickListener(new?OnClickListener()?{?? ?? ????????????@Override?? ????????????public?void?onClick(View?v)?{?? ????????????????PersonService2?service2?=?new?PersonDao2(MainActivity.this);?? ????????????????Map<String,?String>?map?=?service2.viewPerson("?id?=???",?new?String[]?{?"2"?});?? ????????????????Log.i(TAG,?"----?viewPerson?--->"?+?map.toString());?? ????????????}?? ????????});?? ????????button6.setOnClickListener(new?OnClickListener()?{?? ?? ????????????@Override?? ????????????public?void?onClick(View?v)?{?? ????????????????PersonService2?service2?=?new?PersonDao2(MainActivity.this);?? ????????????????//?select?*?from?person?? ????????????????List<Map<String,?String>>?list?=?service2.listPersonMaps(null,?null);?? ????????????????Log.i(TAG,?"----?viewPerson?--->"?+?list.toString());?? ????????????}?? ????????});?? ????}?? ?? ????@Override?? ????public?boolean?onCreateOptionsMenu(Menu?menu)?{?? ????????//?Inflate?the?menu;?this?adds?items?to?the?action?bar?if?it?is?present.?? ????????getMenuInflater().inflate(R.menu.main,?menu);?? ????????return?true;?? ????}?? ?? ????private?void?initComponent()?{?? ????????button1?=?(Button)?findViewById(R.id.button1);?? ????????button2?=?(Button)?findViewById(R.id.button2);?? ????????button3?=?(Button)?findViewById(R.id.button3);?? ????????button4?=?(Button)?findViewById(R.id.button4);?? ????????button5?=?(Button)?findViewById(R.id.button5);?? ????????button6?=?(Button)?findViewById(R.id.button6);?? ????}?? ?? }??
??? 查看 SQLiteDatabase 中, 在上一講中有講到 execSQL (String sql, Object[] bindArgs) 這個方法,在這里Android建議我們在操縱數據庫的時候用以下幾種方式: 1) 插入: insert(String, String, ContentValues) insertOrThrow(String, String, ContentValues) insertWithOnConflict(String, String, ContentValues, int)
2) 更新: update(String, ContentValues, String, String[]) updateWithOnConflict(String, ContentValues, String, String[], int)
3) 刪除: delete(String, String, String[])
[注]這一講中我們就來使用Android推薦的這些操作數據庫的方法來進行數據庫的操作,Demo 還是與上一講類似,讀者可以結合上一講內容來學習,對比之間的不同。
1. 方法概要
??? 1) 查看API文檔 SQLiteDatabase 中的????public long insert (String table, String nullColumnHack, ContentValues values)
??? 插入一行數據到數據庫中 參數: table :?需要插入行的表的名稱 nullColumnHack :?這個參數是可選的,可以為null, SQL 不允許插入一個至少一列都不命名的完全空的行。如果你提供的 values 是空的,而且
沒有已知的的列名,這就是一個空行,這是不能被插入的。如果設置非空,nullColumnHack 參數提供一個可為空的列的名稱,當插入的 values 是空的時候,就將這個列名置為NULL,然后values值插入。 values :?指定行對應的列的值,這個類型很類似Map,key表示列的名稱,values表示列的值 返回值: 返回新插入的行的ID,如果存在錯誤默認返回 -1 [備注]第二個參數翻譯的有些拘謹,我們可以這樣理解
當在沒有任何已知的列名的情況下,values參數為空的時候,insert是會失敗的(數據庫不允許插入一個空行),為了防止Insert()方法要求必須添加一條除了主鍵之外其它字段為Null值的記錄,我們要在這里必須指定一個列名[因為values值是以ContentValues 的形式來存儲的],到時候如果發現將要插入的行為空行時,就會將你指定的這個列名的值設為null,然后再將values值向NULL列中插入。查看源代碼,我們可以發現 Android 中操作數據庫的方法底層也是通過構造SQL語句來實現的。 2)?查看API文檔SQLiteDatabase 中的
public int delete (String table, String whereClause, String[] whereArgs)
刪除操作?
參數: table :?表示表名 whereClause :?可選項,是可以通過 SQL語句中where語句來過濾條件刪除的條目,如果是null 表示刪除所有行 whereArgs :?緊跟第二個參數,作為刪除過濾條件的占位符,詳情請看下面程序 PersonDao2 的 deletePerson() 方法的操作。 返回值: 如果是 0 表示未刪除任何行,如果已經有刪除行的操作 會得到 count > 0的數,表示刪除的行數
3)?查看API文檔SQLiteDatabase 中的
public int update (String table, ContentValues values, String whereClause, String[] whereArgs)更新操作
參數 : table :表示表名 values :??Map 中指定列名用來更新新的值,如果是null 值則為修改為 NULL whereClause :?可選項,支持SQL中的更新語句,用來做條件過濾,如果設置null 則會更新所有行 whereArgs :?緊跟第二個參數,作為更新過濾條件的占位符,詳情請看下面程序 PersonDao2 的updatePerson?() 方法的操作。 返回值: 返回所更新的數據庫的行數
4)查看API文檔SQLiteDatabase 中的
?? 查詢操作 query(),可以發現 SQLiteDatabase 中有大量的 query() 查詢的重載方法,其實這邊它不管怎么重載,都是遵循 SQL 語句來的這里我就剖析一個最為常見的查詢方法,其他的讀者自己查看文檔說明.
參數: distinct :??判斷是否返回的行是唯一值,如果想要返回唯一的行,則為true,否則為false。 table :需要查詢的表的名稱。 columns :需要返回的列,如果要返回所有列則置為null。 selection :過濾需要返回的行,格式遵從SQL中 SQL WHERE 語句(除了Where關鍵字以外).如果返回給定表的所有行,則置為Null。 selectionArgs :?過濾條件的占位符,這里的值會代替過濾語句中 "?"。 groupBy :?過濾條件對行進行分組,格式遵從SQL中 SQL GROUP BY 語句 (除了關鍵字GROUP BY之外),如果不分組,置為Null。 having :?對分組過濾條件的占位符操作。 orderBy :?如何進行排序,遵從SQL中的SQL ORDER BY 語句, 如果是null表示使用默認的排序順序。 limit :是否對數據庫進行分頁的查詢。 返回值:
它返回的是一個游標,這個用法之前有講過,不懂的可以查看前面幾講內容的介紹
2. 代碼實現
1) 程序布局文件 activity_main.xml,這里只是定義了幾個按鈕,就不貼出來了
2) DBOpenHelper.java 用來創建數據庫使用
[java]?view plaincopy3. 程序執行過程
1) 插入數據
2) 刪除ID = 4 的數據
3) 修改ID = 1 的數據
4) 返回查詢的單條記錄和多條記錄
總結
以上是生活随笔為你收集整理的数据存储之 SQLite 数据库操作(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据存储之 SQLite 数据库操作(二
- 下一篇: Hadoop将死,图数据库成为新趋势!