Xamarin.Android之SQLiteOpenHelper
一、前言
在手機中進行網路連線不僅是耗時也是耗電的,而耗電卻是致命的。所以我們就需要資料庫幫助我們儲存離線資料,以便在使用者未使用網路的情況下也可以能夠使用應用的部分功能,而在需要網路連線的功能上採用提示方式,讓使用者決定是否開啟網路。而本節我們將會學習如何訪問資料庫以及提供基本的增刪改查功能,並且使他們儘量的解耦。
二、資料庫
Xamarin.Android下建立本地資料庫與在Java下的方式相同,而我們必須掌握使用SQLiteOpenHelper,因為這個類會簡化我們建立資料的步驟,讓我們只需要關注建立資料庫中的表,並在資料庫版本需要更新時進行操作。其中我們必須實現OnCreate
1 class LocationSqliteOpenHelper : SQLiteOpenHelper 2 { 3 public override void OnCreate(SQLiteDatabase db) 4 { 5 } 6 7 public override void OnUpgrade(SQLiteDatabase db, intoldVersion, int newVersion) 8 { 9 } 10 }
但是我們還需要使用父類的建構函式,指定資料庫的名稱以及初始版本。比如下面的程式碼我們將建立一個名為“test”的資料,並且初始版本為1.。
1 class LocationSqliteOpenHelper : SQLiteOpenHelper 2 { 3 public LocationSqliteOpenHelper(Context context) 4 : base(context, “test”, null,1) 5 { 6 } 7 }
學會了上面的操作,下面我們就可以建立一個名為Test的資料庫,並且該資料庫中含有一個USER表(SQLite資料庫下的主鍵需要為INTEGER型別,並且是自增的)。
1 public class TestSQLiteOpenHelper : SQLiteOpenHelper 2 { 3 public TestSQLiteOpenHelper(Context context) 4 : base(context, "Test", null, 1) 5 { 6 } 7 8 public override void OnCreate(SQLiteDatabase db) 9 { 10 db.ExecSQL("CREATE TABLE USER(id INTEGER PRIMARY KEY NOT NULL,uname TEXT NOT NULL,upwd TEXT NOT NULL)"); 11 } 12 13 public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 14 { 15 db.ExecSQL("DROP TABLE IF EXISTS USER"); 16 OnCreate(db); 17 } 18 }View Code
建立了資料庫物件,下面我們就可以利用這個物件對資料庫進行操作了,首先我們需要在MainActivity中的OnCreate方法中初始化該資料庫物件。
TestSQLiteOpenHelper dbHelper = new TestSQLiteOpenHelper(this);
但是我們還不能直接使用dbHelper訪問資料庫,必須通過它的WritableDatabase屬性或ReadableDatabase屬性獲取對應許可權的資料庫訪問物件,WritableDataBase可以對資料庫進行全部操作,ReadableDatabase可以對資料庫進行讀取操作。他們的返回型別都是SQLiteDataBase。所以我們還要根據需要獲取他們的物件。
SQLiteDatabase db = dbHelper.WritableDatabase;
這樣我們就可以通過db的Insert、Update、Query和Delete進行操作了,當然也可以使用ExecSQL直接執行我們SQL語句。下面我們將逐一介紹這些方法的使用。
1.新增(Insert)
首先是該方法的定義:
public virtual long Insert(string table, string nullColumnHack, ContentValues values);
其中引數的含義如下:
table:需要插入的表名。
nullColumnHack:當values為空或裡面的值都為空時,資料庫是不允許插入一個空行的,如果需要插入空行,則需要指定一個欄位名稱,這樣當發生如上情況後將會將該欄位設為NULL然後在嘗試插入。
values:需要插入的資料。
關於前兩個引數很簡單不用過多介紹,如要介紹的是最後一個引數,它是一個ContentValues型別,通過它我們可以大大的簡化自己拼接插入語句的繁瑣,比如下面我們可以設定uname欄位的值為yzf,upwd的值為123。
1 ContentValues cv = new ContentValues(); 2 cv.Put("uname","yzf"); 3 cv.Put("upwd","123");
關鍵就是Put方法,它擁有以下的過載方法。
1 public void Put(string key, bool value); 2 public void Put(string key, byte[] value); 3 public void Put(string key, double value); 4 public void Put(string key, float value); 5 public void Put(string key, int value); 6 public void Put(string key, long value); 7 public void Put(string key, sbyte value); 8 public void Put(string key, short value); 9 public void Put(string key, string value);
通過這些過載方法我們就可以插入不同型別的引數了,當然我們也可以通過Remove方法刪除,如果我們需要為某個欄位插入NULL值可以使用PutNull方法,判斷某個欄位是否存在可以用ContainsKey方法,最後就是對應的獲取不同欄位的值。
1 public Object Get(string key); 2 public bool GetAsBoolean(string key); 3 public sbyte GetAsByte(string key); 4 public byte[] GetAsByteArray(string key); 5 public double GetAsDouble(string key); 6 public float GetAsFloat(string key); 7 public int GetAsInteger(string key); 8 public long GetAsLong(string key); 9 public short GetAsShort(string key); 10 public string GetAsString(string key);
簡單的介紹完ContentValues的使用,下面我們將使用它來新增一條資料,比如下面的程式碼將新增一條資料到User表中。
long id = db.Insert("User", null, cv);
返回值則為所插入資料的主鍵。
2.查詢(Query)
首先是該方法的定義:
1 public virtual ICursor Query(string table, string[] columns, string selection, string[] selectionArgs, string groupBy, string having, string orderBy); 2 public virtual ICursor Query(string table, string[] columns, string selection, string[] selectionArgs, string groupBy, string having, string orderBy, string limit); 3 public virtual ICursor Query(bool distinct, string table, string[] columns, string selection, string[] selectionArgs, string groupBy, string having, string orderBy, string limit);
其中引數的含義如下:
table:需要查詢的表名
columns:需要獲取的欄位,如果傳入null則表示獲取所有欄位
selection:條件語句,其中我們可以實用”?”作為引數的佔位符(不同於SQL SERVER中的@)
selectionArgs:條件引數,用於替換查詢語句中的”?”
groupBy:分組語句
having:分組條件
orderBy:排序語句
limit:分頁語句(如”1,3”表示獲取第1到第3的資料共3條)
之前通過Insert插入的資料,此時我們可以通過Query方法從資料庫中獲取,比如下面的程式碼
ICursor ic = db.Query("User", new string[] { "id", "uname", "upwd" }, " id = ? ", new string[] { id.ToString() }, null, null, null);
該方法最後會返回一個實現了ICursor介面的物件,利用這個介面我們就可以從中獲取資料了,下面我們獲取其中的使用者名稱和密碼
1 ic.MoveToFirst(); 2 string uname = ic.GetString(ic.GetColumnIndex("uname")); 3 string upwd = ic.GetString(ic.GetColumnIndex("upwd"));
因為ICursor是針對一個結果集的,所以我們需要先定位到第一條資料,所以採用MoveToFirst方法,然後通過GetString獲取引數,但是還需要傳遞一個欄位的位置,所以我們還需要使用GetColumnIndex獲取指定欄位名稱的位置。
下面是關於ICursor方法的介紹
Count:獲取多少條資料
IsAfterLast:當前是否在最後一條資料之後
IsBeforeFirst:當前是否在第一條資料之前
IsClosed:是否已關閉
IsFirst:是否是第一條資料
IsLast:是否是最後一條資料
Position:當前位置
GetColumnIndex:根據欄位名獲取位置,如果不存在該欄位則返回-1
GetColumnName:根據位置獲取欄位名
MoveToFirst:移動到第一條資料
MoveToFirst:移動到最後一條資料
MoveToNext:移動到下一條資料
MoveToPosition:移動指定的位置
MoveToPrevious:移動到上一條資料
以下是根據位置獲取對應型別的資料
GetDouble,GetFloat,GetInt,GetLong,GetShort,GetString
3.更新(Update)
首先是該方法的定義:
Update(string table, ContentValues values, string whereClause, string[] whereArgs);
其中引數的含義如下
table:需要更新的資料所在的表
values:更新後欄位的值
whereClause:查詢語句
whereArgs:查詢語句中需要的引數
有了插入、查詢資料的幫助下,我們可以在插入資料之後更新這條資料,然後再通過Query獲取該資料,檢視資料的是否變動。
1 ContentValues ncv = new ContentValues(); 2 ncv.Put("uname", "zn"); 3 ncv.Put("upwd", "456"); 4 db.Update("User", ncv, " id = ? ", new string[] { id.ToString() });
這裡的條件語句跟查詢中的語句是類似的,然後我們檢視獲取的資料可以發覺的確發生了修改。
4.刪除(Delete)
首先是該方法的定義:
public virtual int Delete(string table, string whereClause, string[] whereArgs);
關於引數的說明跟Update是相同的,所以實用方式這裡就不做介紹了。
全部例項的全部程式碼如下所示:
TestSQLiteOpenHelper.cs
1 public class TestSQLiteOpenHelper : SQLiteOpenHelper 2 { 3 public TestSQLiteOpenHelper(Context context) 4 : base(context, "Test", null, 1) 5 { 6 } 7 8 public override void OnCreate(SQLiteDatabase db) 9 { 10 db.ExecSQL("CREATE TABLE USER(id INTEGER PRIMARY KEY NOT NULL,uname TEXT NOT NULL,upwd TEXT NOT NULL)"); 11 } 12 13 public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 14 { 15 db.ExecSQL("DROP TABLE IF EXISTS USER"); 16 OnCreate(db); 17 } 18 }
MainActivity的OnCreate中
1 TestSQLiteOpenHelper dbHelper = new TestSQLiteOpenHelper(this); 2 SQLiteDatabase db = dbHelper.WritableDatabase; 3 4 ContentValues cv = new ContentValues(); 5 cv.Put("uname","yzf"); 6 cv.Put("upwd","123"); 7 long id = db.Insert("User", null, cv); 8 9 ContentValues ncv = new ContentValues(); 10 ncv.Put("uname", "zn"); 11 ncv.Put("upwd", "456"); 12 db.Update("User", ncv, " id = ? ", new string[] { id.ToString() }); 13 14 ICursor ic = db.Query("User", new string[] { "id", "uname", "upwd" }, " id = ? ", new string[] { id.ToString() }, null, null, null); 15 ic.MoveToFirst(); 16 string uname = ic.GetString(ic.GetColumnIndex("uname")); 17 string upwd = ic.GetString(ic.GetColumnIndex("upwd"));