微軟WP7本機資料庫解決方案之Sqlite
轉自:http://tech.it168.com/a2011/0511/1188/000001188936_all.shtml
無論是從使用者的角度來看還是從開發人員的角度來看,Windows Phone 7給我們帶來眾多的新的和令人振奮的功能。與此同時,當前的Windows Phone 7系列也的確存在令許多使用者失望的缺憾。一個代表性的遺憾便是,Windows Phone 7缺乏本地資料庫API支援—當前的Windows Phone 7作業系統僅提供通過XML、客戶端獨立儲存和雲端儲存等幾種有限的資料訪問支援。那麼,就本地資料庫功能來說,我們真的有沒有其他的選擇了嗎?當然不是這樣。如今各種開源社團如火如荼,已經有一些開發人員和團隊一直努力在填補這一方面的空白。
請注意,儘管目前已有多個嘗試實現了Windows Phone 7本地資料庫支援,但最後,這些系統都需要執行於Windows Phone 7提供的獨立儲存基礎之上。在本系列文章中,我將向你介紹上述成員之一-Sqlite Client for Windows Phone。這是一種新的,功能強大且易於使用的Windows Phone 7本機資料庫解決方案,該系統公佈於著名的開源網站CodePlex。篇幅所限,我僅介紹在Windows Phone 7系統中使用Sqlite Client for Windows Phone程式設計的部分技巧。
[備註]本系列文章中的案例程式除錯環境包括:
1. Windows 7;
2. .NET 4.0;
3. Visual Studio 2010;
4. Windows Phone Developer Tools RTW;
5. Sqlite Client for Windows Phone (http://sqlitewindowsphone.codeplex.com/);
6. (推薦) sqlite-manager (http://code.google.com/p/sqlite-manager/);
7. (推薦) MVVM Light Toolkit (http://mvvmlight.codeplex.com/).
一、Sqlite Client for Windows Phone簡介
大家都知道,SQLite是一個著名的開源的嵌入式的資料庫系統,目前已經提供對於iOS和Android的良好支援。在此,應當讓我們感謝Dan Ciprian Ardelean,是他帶給我們WP7版本的SQLite-C#-SQLite!最近幾個月,作者對早期的版本又進行了更新,得到一個功能更強大和更容易使用的解決方案,改名為Sqlite Client for Windows Phone,在知名的開源網站CodePlex上釋出,網址是http://sqlitewindowsphone.codeplex.com/releases。
▲圖1. 下載Sqlite Client for Windows Phone的介面截圖
Sqlite Client for Windows Phone進行大範圍的更新,如提供對於布林型別、大型資料(Blobs)以及事務的全面支援,此外,下載包中還一併提供了一個全面的示例,供開發者學習之用。
▲圖2. Sqlite Client for Windows Phone原始碼工程及示例工程架構
接下來的操作就很簡單了:重新構建原始碼工程,得到一個程式集Community.CsharpSqlite.WP.dll(Release版本大小是525 KB)。然後,在你的WP7 Silverlight 專案中新增對該程式集的引用。最後,你便可以使用Sqlite Client for Windows Phone提供的本地資料庫支援功能了。
二、Sqlite Client for Windows Phone基礎類庫剖析
如果您以前有過任何基於SQL指令碼的資料庫程式設計經驗,那麼您可以輕鬆地使用Sqlite Client for Windows Phone功能。特別值得一提的是,此工程建基於以前的C#-SQLite專案之一,通過引入幾個幫助器類(在檔案SQLiteClient.cs),即SQLiteException、SQLiteConnection和SQLiteCommand,進一步簡化了基本的資料庫和表相關操作。接下來的幾幅圖展示了Sqlite Client for Windows Phone中提供的主要元件及其之間的關聯關係。
▲圖3. Sqlite Client for Windows Phone最頂層元件
▲圖4. SQLiteConnection類中的主要元件
▲圖5. SQLiteCommand類中的主要元件
怎麼樣!如果您以前熟悉任何基於SQL的資料庫開發,相信上面的這些元件對您會非常親切吧。
先別急,在正式使用Sqlite Client for Windows Phone之前,有必要再向您介紹另外一個非常有用的工具,名為sqlite-manager (http://code.google.com/p/sqlite-manager/)。這個工具是以FireFox外掛的方式提供的。到現在您應該明白了,絕大多數與SQLite資料庫相關的操作,例如建立SQLite資料庫、表、檢視、索引等等,都可以通過sqlite-manager輕鬆完成。
1.使用SQLite Manager簡化資料庫管理
如前所述,SQLite Manager是一個Firefox外掛,使用Firefox的載入項管理器你可以很容易地獲取和安裝這個控制元件(圖6)。
▲圖6. 使用Firefox的載入項管理器獲取和安裝SQLite Manager外掛
如圖所示,如果你開啟Firefox的外掛管理器,然後輸入“SQLite Manager”搜尋文字,你會很容易檢索到此載入項。然後,您可以點選按鈕“新增到Firefox... ”開始下載並安裝SQLite Manager。請注意,在Firefox的提示後,你應該重新啟動Firefox以完成安裝。
使用SQLite Manager是容易的。說實在的,這是我第一次使用SQLite Manager,我發現這個工具功能強大而且極易上手。如果您使用過VB6中,你可能熟悉其中內建的資料庫管理工具-VisData(以便以內建方式建立小型的Access資料庫)。說實話,VisData確實是不容易使用,但在當時我們覺得已經相當不錯了。現在,你只須記住,SQLite Manager的功能要比VisData強大1000倍。下圖展示了SQLite Manager的一個使用快照。
▲圖7. SQLite Manager使用快照
從圖中可見,你可以使用SQLite Manager來實現幾種各種SQLite相關操作。請注意,要想了解更多的有關於SQLite的概念及詳細使用語法,請從這款外掛的幫助選單中尋找答案。
另外,你也會注意到,在本文簡單的示例工程中,我僅建立了一個表格Customer,對應的資料庫檔案為database1.sqlite(如圖8所示)。
▲圖8. 使用SQLite Manager定義表格Customer欄位
在建立完資料庫database1.sqlite後,關閉SQLite Manager外掛。然後,把此檔案複製或移動到對應示例工程WP7SQLiteClient的根目錄下。請注意,接下來,把它的Build Action屬性設定為Resource模式。設定成這種模式的原因與接下來的操作方式相關。如果選擇Content模式,則在後臺的示例工程中你需要修改對應的部分原始碼。
2.一個有用的工具類-DBHelper
如上所述,Sqlite Client for Windows Phone使用眾所周知的SQL操作針對典型的資料庫操作提供了一個高層次的封裝。因此,在Silverlight for Windows Phone 7程式設計中為了處理SQLite資料庫操作,我們可以直接使用在檔案SQLiteClient.cs中定義的物件(在源庫專案),即SQLiteException、SQLiteConnection和SQLiteCommand等。
雖然Sqlite Client for Windows Phone並沒有提供與獨立儲存的直接互動,但顯然增加對獨立儲存支援是必要的,這樣可以改善系統的效能。因此,我們可以進一步封裝前面提到的SQLiteClient物件。為此,Chris開發了一個非常好用的實用工具類,叫做DBHelper。為了應用於我們自己的示例,我對它做了輕微的修改。完整的原始碼如下。
列表1:更新版本的工具類DBHelper
using SQLiteClient;
using System.Linq;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace WP7SQLiteClient.Helpers
{
public class DBHelper
{
private String _dbName;
private SQLiteConnection db = null;
public DBHelper(String assemblyName, String dbName)
{
IsolatedStorageFile store =IsolatedStorageFile.GetUserStoreForApplication();
if (!store.FileExists(dbName))
{
CopyFromContentToStorage(assemblyName, dbName);
}
_dbName = dbName;
}
~DBHelper()
{
Close();
}
private void Open()
{
{
db = new SQLiteConnection(_dbName);
db.Open();
}
}
private void Close()
{
if (db != null)
{
db.Dispose();
db = null;
}
}
//Insert operation
public int Insert(T obj, string statement) where T : new()
{
try
{
Open();
SQLiteCommand cmd = db.CreateCommand(statement);
int rec = cmd.ExecuteNonQuery(obj);
return rec;
}
catch (SQLiteException ex)
{
System.Diagnostics.Debug.WriteLine("Insert failed: " + ex.Message);
throw ex;
}
}
// Delete operation
public void Delete(string statement) where T : new()
{
try
{
SQLiteCommand cmd = db.CreateCommand(statement);
cmd.ExecuteNonQuery();
}
catch (SQLiteException ex)
{
System.Diagnostics.Debug.WriteLine("Deletion failed: " + ex.Message);
throw ex;
}
}
//Query operation
public List SelectList(String statement) where T : new()
{
Open();
SQLiteCommand cmd = db.CreateCommand(statement);
var lst = cmd.ExecuteQuery();
return lst.ToList();
}
public ObservableCollection SelectObservableCollection(String statement)
where T : new()
{
List lst = SelectList(statement);
ObservableCollection oc = new ObservableCollection();
foreach (T item in lst)
{
oc.Add(item);
}
return oc;
}
private void CopyFromContentToStorage(String assemblyName,String dbName)
{
IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication();
System.IO.Stream src =
Application.GetResourceStream(
new Uri("/" + assemblyName + ";component/" + dbName,
IsolatedStorageFileStream dest =
new IsolatedStorageFileStream(dbName,
System.IO.FileMode.OpenOrCreate,
System.IO.FileAccess.Write, store);
src.Position = 0;
CopyStream(src, dest);
dest.Flush();
dest.Close();
src.Close();
dest.Dispose();
}
private static void CopyStream(System.IO.Stream input,
IsolatedStorageFileStream output)
{
byte[] buffer = new byte[32768];
long TempPos = input.Position;
int readCount;
do
{
readCount = input.Read(buffer, 0, buffer.Length);
if (readCount > 0)
{
output.Write(buffer, 0, readCount);
}
} while (readCount > 0);
input.Position = TempPos;
}
}
}
順便說一句,對於上面這個幫助類我也沒有提供細緻的優化編碼。希望讀者根據您的相關工作能夠繼續進行這項工作(例如提供更好的泛型化的CRUD支援)並分享給廣大網友。簡言之,我主要是增加了插入和刪除方法。上面的程式碼中最引起您注意是地方一定是方法CopyFromContentToStorage,正是藉助這個方法我們實現了上述目標-建立起SQLite資料庫與獨立儲存的關係。
三、小結
本文中簡要介紹了Sqlite Client for Windows Phone的主要功能及相關的輔助開發工具。在接下來的第二篇文章中,我們將具體構建一個簡單的Windows Phone 7客戶端應用程式,當然要涉及到Sqlite Client for Windows Phone的基本程式設計技巧。
相關文章
- 海量資料庫解決方案資料庫
- IOS資料儲存之Sqlite資料庫iOSSQLite資料庫
- 雲資料庫安全解決方案資料庫
- 資料庫回檔解決方案資料庫
- 本地IDC機房資料庫容災解決方案資料庫
- 【WP7】本地資料庫使用資料庫
- iOS端資料庫解決方案分析iOS資料庫
- 分庫解決方案—資料儲存
- shutdown immediate 持久無法關閉資料庫之解決方案資料庫
- Laravel資料庫測試的另一種方案-SQLiteLaravel資料庫SQLite
- sqlite 資料庫的資料字典SQLite資料庫
- sqlite操作--- oracle資料庫中的資料導進sqliteSQLiteOracle資料庫
- WP7“Navigation is not allowed when the task is not in the foreground.”解決方案Navigation
- 一次資料庫匯入解決方案資料庫
- 大型資料庫應用解決方案總結資料庫
- 資料庫大型應用解決方案總結資料庫
- 【Java】操作Sqlite資料庫JavaSQLite資料庫
- SQLite資料庫管理器:SQLPro for SQLite for MacSQLite資料庫Mac
- 大資料解決方案大資料
- 深入剖析資料庫核心之事務的本質 | 附下一代分散式資料庫 OceanBase 解決方案資料庫分散式
- android sqlite資料庫 新增資料AndroidSQLite資料庫
- Android資料庫升級不丟失資料解決方案Android資料庫
- MYSQL資料庫表記錄刪除解決方案MySql資料庫
- 資料庫行業解決方案都寫了啥資料庫行業
- MySQL資料庫常見錯誤及解決方案MySql資料庫
- 使用 Applet 連線資料庫 解決方案.....APP資料庫
- SQLPro for SQLite Mac(SQLite資料庫管理工具)SQLiteMac資料庫
- 高效操控SQLite資料庫,盡在SQLPro for SQLite for MacSQLite資料庫Mac
- 本機資料庫資料庫鏈無法訪問遠端資料庫資料庫
- Python操作SQLite資料庫PythonSQLite資料庫
- Python 操作 SQLite 資料庫PythonSQLite資料庫
- sqlite3資料庫操作SQLite資料庫
- 微軟解決方案架構 (轉)微軟架構
- 資料庫與快取資料一致性解決方案資料庫快取
- air 讀取sqlite的Date型別 解決方案AISQLite型別
- cocos2dx之引入Sqlite3資料庫SQLite資料庫
- 使用sqlite3 模組操作sqlite3資料庫SQLite資料庫
- python用sqlite3模組操作sqlite資料庫PythonSQLite資料庫