標籤:android style blog http color os 使用 io strong
一、前言
通過《Xamarin.Android之SQLiteOpenHelper》和《Xamarin.Android之ContentProvider》的學習,我們已經掌握了如何使用特定於該平台的資料庫操作。但是這樣卻和Xamarin所宣稱的跨平台相違背了,因為這樣我們就需要針對不同的平台編寫不同的代碼,而本章將使用Github上的開源項目SQLite.NET去解決這個問題,從而可以實現跨平台,減少代碼的重複。
關於該開源項目請點我
二、準備工作
因為這個庫很大,而我們只需要其中的一個.cs檔案就可以了,所以筆者這裡已經封裝好了一個庫,裡面不僅包含了這個庫,還包含了可以跨平台的網路連接。
點我下載
因為該庫還使用了一個json庫,所以讀者也一併要下載並引用
點我下載
然後建立一個Android Application項目(.net 4.0)並且SDK版本設定為14(Android 4.0),下面我們就可以開始正式學習了。
三、本文
1.引用命名空間
開啟MainActivity類並在頂部加上如下引用
1 using NSCPAndroid.SQLite;
2.建立一個映射類
有過一定開發經驗的人一定會很熟悉ORM,筆者平時用的最多的就是EF、Castle Active Record。當然還有很多其他更優秀的架構。不熟悉的人也沒有關係,下面我們只是建立一個類,而這個類的結構完全是對應到資料庫中的表的。比如筆者在這裡建立一個名為Stock的表:
1 [Table("Stock")]2 public class StockTable3 {4 [PrimaryKey, AutoIncrement, Column("_id")]5 public int Id { get; set; }6 7 [MaxLength(8)]8 public string Symbol { get; set; }9 }
其中我們可以看到Table這個註解屬性,含義就是這個類對應到資料庫中的表名。讀者不要誤認為是依照類名,下面就是兩個欄位其中關鍵的就是主鍵,因為SQLite規定主鍵必須由自身維護,所以這裡我們使用了PrimaryKey註解屬性工作表示該屬性為主鍵,AutoIncrement表示該主鍵為自增,最後就是Column表示該欄位對應到該表的欄位名(名字必須為_id),下面一個就是我們自己的欄位了,筆者使用了MaxLength表示該欄位最大可以儲存八個字元。
關於更多的註解屬性可以看下面的介紹。
[PrimaryKey]:表示該表的主鍵,只能用於Int類型的屬性。
[AutoIncrement]:用於需要自增的屬性,每插入一條新資料該欄位都會自增,只能用於Int類型。
[Column(name)]:用來表示指定屬性對應到表中欄位的名稱,如果不加該屬性則表中的欄位名與屬性名稱相同。
[Table(name)]:用來表示指定類對應到資料庫中的表名稱,如果不加該屬性則資料庫中的表名稱與該類名稱相同。
[MaxLength(value)]:用來限制欄位能夠儲存的最長字元長度。
[Ignore]:表示忽略該屬性,從而不會在表中產生對應的欄位。
[Unique]:表示該屬性的值必須在表中唯一。
3.建立資料庫連接
我們需要指定資料庫所儲存的路徑,同時還要開啟該資料庫。如果不存在該資料庫,則會自動建立該檔案。下面的代碼我們將擷取資料庫的路徑並開啟該資料庫:
1 string dbPath = Path.Combine(System.Environment.2 GetFolderPath(System.Environment.SpecialFolder.Personal),"ormdemo.db3");3 var db = new SQLiteConnection(dbPath);
這裡要注意我們用的是SQLiteConnection開啟該資料庫的,而不是SqlConnection。成功開啟該資料庫之後剩下的工作我們只需要利用db就可以輕鬆完成了,到現在為止我們僅僅建立了一個空的資料庫,裡面還不存在任何錶。
4.建立表
第2步我們已經建立好了一個表的結構,下面我們將在資料庫中建立對應的表,我們只需要通過下面的代碼就可以輕鬆的建立一個表了:
1 db.CreateTable<StockTable>();
或者下面這個方式也一樣可以:
1 db.CreateTable(typeof(StockTable));
建立完之後表還是空的,所以接下來我們需要插入幾條資料,這樣才能介紹其他的操作。
註:實際運用中一定會有人想找如何判斷該表是否已經建立的方法,其實沒有必須要找,即使重複的執行該操作,也不會影響什麼,表一旦建立之後在執行就不會重新建立了。
5.插入資料
這裡我們直接通過建立StockTable的執行個體來插入到資料庫中,比如下面的代碼我們將會插入一條資料:
1 var newStock = new StockTable();2 newStock.Symbol = "First";3 db.Insert(newStock);
是不是十分簡單,僅僅只需要調用Insert即可,該方法還會返回插入資料的主鍵。但是這隻是插入一條資料,如果我們需要插入多條資料呢?當然不可能用foreach,已經提供了另一個方法InsertAll,比如下面的樣本將會同時插入多條資料:
1 List<StockTable> stocks = new List<StockTable> 2 { 3 new StockTable{ 4 Symbol = "First" 5 }, 6 new StockTable{ 7 Symbol = "Second" 8 } 9 };10 db.InsertAll(stocks);
如果讀者需要驗證下是不是插入了,我們可以擷取該表有多少資料即可,比如下面的代碼:
1 int count = db.Table<StockTable>().Count();
這時表裡已經有資料了,下面我們就需要進行查詢。
6.查詢資料
首先介紹最簡單的查詢方式,就是依靠id來直接擷取。當然我們不需要拼接任何SQL,只需要通過下面這段代碼就可以擷取id為1的資料了:
1 var item = db.Get<StockTable>(1);
但是大多數情況下我們都需要通過條件陳述式進行查詢,那樣我們就需要使用SQL語句了,比如下面的查詢語句,我們將查詢Symbol開頭為“F”的資料:
1 var items = db.Query<StockTable>(" select * from Stock where Symbol like ? ", "F%");
相信那些對技術比較追求的人一定知道Linq,它讓我們擺脫的拼接SQL語句的尷尬,使得查詢變的簡單有趣(複雜的查詢還是需要採用SQL,甚至是預存程序等),當然在這裡我們依然可以使用這一特性,下面我們將上面的代碼改寫成Linq:
1 var items = (from item in db.Table<StockTable>()2 where item.Symbol.StartsWith("F")3 select item).GetEnumerator();
筆者為了能夠更快的查看結果,所以使用了GetEnumerator,實際使用中不一定需要。如果讀者喜歡最原始的查詢可以用ExecuteScalar方法。
註:linq的查詢是屬於延遲查詢的,意味著在查詢的那一刻並沒有把結果查詢出來,而是等待你使用它的時候才查詢。
推薦:
1.Jesse Liu的隨筆《快樂的lambda運算式》,個人感覺很有意思,也很有用。
2.關於Linq如何?動態查詢的文章點我,動態查詢可以認為是用字串拼接Linq的部分語句,這樣做的目的是為瞭解決某些特殊場合下的使用。
關於查詢資料到此結束了,下面我們將學習剩下的兩個操作分別是更新和刪除。
7.更新和刪除資料
首先我們先將更新資料,因為它的操作跟插入資料是一樣的存在Update和UpdateAll,只是資料的主鍵需要有資料,否則無法定位是更新哪個資料,下面我們將示範如何利用Update更新資料:
1 var result = (from item in db.Table<StockTable>()2 where item.Symbol.StartsWith("F")3 select item).First();4 result.Symbol = "Third";5 db.Update(result);6 7 result = db.Get<StockTable>(result.Id);
既然是更新當然需要先擷取一條資料然後更新,最後還要從資料庫中拿出來,確定是否已經更新成功。下面我們繼續刪除操作:
1 var result = (from item in db.Table<StockTable>()2 where item.Symbol.StartsWith("T")3 select item).First();4 5 db.Delete<StockTable>(result.Id);
如果你需要刪除整個表的資料只需要使用DeleteAll即可,當然這些操作都是有限的,所以我們還需要支援SQL的方法,那麼我們可以使用Execute即可。
最後結果給大家一個本人比較喜歡ORM,用在網站開發上的
Xamarin.Android之SQLite.NET ORM