Xamarin.Android之SQLiteOpenHelper


一、前言

在手機中進行網絡連接不僅是耗時也是耗電的,而耗電卻是致命的。所以我們就需要數據庫幫助我們存儲離線數據,以便在用戶未使用網絡的情況下也可以能夠使用應用的部分功能,而在需要網絡連接的功能上采用提示方式,讓用戶決定是否打開網絡。而本節我們將會學習如何訪問數據庫以及提供基本的增刪改查功能,並且使他們盡量的解耦。

 

二、數據庫

Xamarin.Android下創建本地數據庫與在Java下的方式相同,而我們必須掌握使用SQLiteOpenHelper,因為這個類會簡化我們創建數據的步驟,讓我們只需要關注創建數據庫中的表,並在數據庫版本需要更新時進行操作。其中我們必須實現OnCreate方法和OnUpgrade方法,OnCreate方法僅會在數據庫不存在的情況下才執行,所以不會重復執行。比如下面的代碼。

 1         class LocationSqliteOpenHelper : SQLiteOpenHelper
 2         {
 3             public override void OnCreate(SQLiteDatabase db)
 4             {
 5             }
 6 
 7             public override void OnUpgrade(SQLiteDatabase db, int oldVersion, 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的InsertUpdateQueryDelete進行操作了,當然也可以使用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:移動到上一條數據

以下是根據位置獲取對應類型的數據

GetDoubleGetFloatGetIntGetLongGetShortGetString

 

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 }

 

 

MainActivityOnCreate

 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"));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM