開發Windows Mobile簡單dict字典-以SQLite為例
根據<<拆解 DICT dictionary>>這一篇分享自己拆解*.dict檔的內容並另存成文字檔的方式,這一次是使用把拆解出來的內容,
儲存於SQLite小型database之中。這篇的內容,不會提太多相關於SQLite的原理,我打算分享如何在Windows Mobile上開發
使用SQLite的使用方式,另外提供自己能夠拿來用的於自己手機上的小型字典。
要透過C#開始支援SQLite的程式,可以透過System.Data.SQLite所提供的Librar來開發程式。目前的版本支援到 1.0.65.0,
該社群的人所撰寫的Library,還提供完整的說明文件:SQLite.NET.chm,所以大家如果這篇看了還不是很清楚的話,可以下載
System.Data.SQLite的binaries版本下來仔細閱讀。以下將說明開發此次範例的程式說明:
1. 建立字典資料庫
可參考<<拆解 DICT dictionary>>所提供的拆解方式,將原本文章針對寫到文字檔的對象改為寫入SQLite資料庫之中,因此,下方
只提供C#如何建立與連線SQLite資料庫的簡單程式片段。另外,建立的拆解C#應用程式專案,記得將System.Data.SQLite所提供
的二個重要DLL(System.Data.SQLite.DLL與System.Data.SQLite.Linq.dll),加入該專案的參考之中。(建議把該檔案放入至開發
專案的\bin\Debug目錄下)如下圖:
1-1. 程式片段:建立一個資料庫,新增一個Vocabulary資料表(具有v_id, word, meaning三個欄位)、並建立該Vocabulary資料表的index。
1: string filePath="dictionary.db";
2: SQLiteConnection.CreateFile(filePath);
3: using (SQLiteConnection sqliteCon = new SQLiteConnection("Data Source=" + filePath))
4: {
5: sqliteCon.Open();
6: string sql = "CREATE TABLE Vocabulary ('v_id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , 'word' VARCHAR, 'meaning' TEXT); " +
7: "CREATE INDEX 'word_idx' ON 'Vocabulary' ('word' ASC); ";
8: SQLiteCommand sqliteCmd = new SQLiteCommand(sql, sqliteCon);
9: int isSus = sqliteCmd.ExecuteNonQuery();
10: if (isSus == -1) {
11: MessageBox.Show("Error");
12: }
13: else {
14: MessageBox.Show("Create DataBase File Successful!");
15: }
16: sqliteCmd.Dispose();
17: sqliteCon.Clone();
18: }
1-2. 將拆解好的資料,填寫回資料庫之中。
1: using (SQLiteConnection sqliteCon = new SQLiteConnection("Data Source=" + filePath))
2: {
3: sqliteCon.Open();
4: SQLiteCommand sqliteCmd = new SQLiteCommand();
5: sqliteCmd.Connection = sqliteCon;
6: sqliteCmd.CommandText = "INSERT INTO Vocabulary (word, meaning) Values(@word, @meaning); ";
7: sqliteCmd.Parameters.Add("@word", DbType.String);
8: sqliteCmd.Parameters.Add("@meaning", DbType.String);
9: for (i = 0; i < count; i++)
10: {
11: sqliteCmd.Parameters["@word"].Value = wordList[i].word_str;
12: sqliteCmd.Parameters["@meaning"].Value = System.Text.Encoding.UTF8.GetString(baBuffer, 0, wordList[i].data_size).Replace("\n", "\r\n");
13: result=sqliteCmd.ExecuteNonQuery();
14: }
15: sqliteCmd.Dispose();
16: sqliteCon.Close();
17: }
2. 建立一行動裝置程式
建立智慧型行動裝置程式時,一樣要加入支援CompactFramework資料夾中的System.Data.SQLite.DLL與SQLite.Interop.065.DLL,
你會發現透過VS2008加入SQLite.Interop.065.DLL時會出現錯誤沒有辦法讓你加入或者是透過Windows Mobile模擬器執行程式時會發
現出現錯誤訊息,可以按照下方所提供的解決方法來解決這個問題。(另外,拆解好的資料庫也是透過下方的方式加入到模擬器中測試)。
【注意】
如果你在編譯程式的過程中,進行Debug模式下,遇到「Can't find PInvoke DLL 'SQLite.Interop.060.DLL」這段文字時,主要是因為,
我們都知道要引用別人的DLL檔到程式開發時,會先透過Visual Sutdio中的「加入參考」去選擇所要參考的Library,不過,你會發現在
加入SQLite.Interop.060.DLL會失敗,加不進去參考,那該怎辦呢?常見的作法,會直接甘脆把該SQLite.Interop.060.DLL直接Copy到
專案編輯目錄中的 \bin 底下,讓程式在執行時,直接Copy到編譯的目錄下,但Visual Studio並不會幫你把該DLL自動Copy到WM Emulator
因此,你需要自行透過手動的方式,把SQLite.Interop.060.DLL複製你程式執行的目錄下(也就是跟.exe相同的目錄),即可解決該問題。
作法步驟說明如下:
1. 透過Visual Studio 2008所提供的 Remote File Viewer 工具來連線WM Emulator
該工具位在:「開始\Visual Studio 2008\CE Remote Tools\」之中,或是「C:\Program Files\CE Remote Tools\5.01\bin\ccfilevw.exe"」。
2. 開啟 Remote File Viewer 工具後,選擇目前正在使用的 WM Emulator。
3. 將SQLite.Interop.060.DLL透過Export File的功能,輸入至程式執行的目錄。(假設專案目錄為dictApp,則將檔案放置該目錄下)
2-1. 程式片段:當按照上面步驟加入SQLite.Interop.060.DLL與字典資料庫之中,接下來的程式撰寫就跟我們在寫一般Win Form操作
SQLite一般。如下範例:
1: using (SQLiteConnection sqliteCon = new SQLiteConnection("Data Source=" + filePath))
2: {
3: sqliteCon.Open();
4: SQLiteCommand sqliteCmd = new SQLiteCommand();
5: sqliteCmd.Connection = sqliteCon;
6: sqliteCmd.CommandText = "SELECT word, meaning FROM vocabulary WHERE word =@word";
7: sqliteCmd.Parameters.Add("@word", DbType.String);
8: sqliteCmd.Parameters["@word"].Value = txtWord.Text;
9: SQLiteDataReader sqliteDR = sqliteCmd.ExecuteReader();
10: if (sqliteDR.Read()) {
11: result = sqliteDR["meaning"].ToString();
12: }
13: else {
14: result = "未找到相關[" + _word + "]的字義!";
15: }
16: sqliteDR.Close();
17: sqliteDR.Dispose();
18: }
【開發後記】
當初在不使用SQLite做為字典存儲資料之前,我原本是預設使用DICT的檔案格式(*.idx與*.dict),透過二個原始的檔案,在程式執行時再
進行讀取字典索引檔(idx)到記憶體中,方便查詢,但測試出來的結果,發現這樣的做法,對於一些手機他記憶體比較小或是開啟多個程式
時,要讀取與剖析這份idx會花上大量的時間,因此取消透過實體DICT檔案格式,改由將DICT檔格拆解並儲存於SQLite之中,透過原有SQLite
本身對於資料搜尋與最佳化的方式,讓效能有所改善。 另外,我針對此資料庫新增了該單字資料表的索引,並且透過SQLite的Compact技術
將資料庫進行壓縮,讓檔案大小變的更適合於行動裝置上使用,下一篇將會更詳細說明開發的成果與設計方式。
References:
http://sqlite.phxsoftware.com/forums/p/1569/6785.aspx#6785
http://circlep.pixnet.net/blog/post/25380869