若要Build附有SQLite的專案,則必須使用Pro版本
或者是先編出沒有dll的apk → 將副檔名從apk改成zip並解壓縮 → 將dll檔放入專門存放dll的資料夾內 → 將整個解壓縮的檔案重新使用「僅儲存」壓縮回去並將副檔名從zip改成apk → 上網找apk簽名的程式將檔案重新簽名 → 完成。
2016/03/04版本更新內容如下:
1.openDatabase改名為openDatabaseConnecting
2.增加插入大量資料的Method,使用方式為依序呼叫insertBigDataInitialize、insertBigDataInto、insertBigDataWrite
insertBigDataInitialize:初始化大量資料寫入功能
insertBigDataInto:準備將資料按順序寫入資料表內,一次限寫一row的資料。(可重複呼叫多次)
insertBigDataWrite:將insertBigDataInto儲存的大量資料一次性的寫入資料庫內。(呼叫過這個Method後,若要再插入新的大量資料,請從insertBigDataInitialize重新開始)
2016/03/02版本更新內容如下:
1.修正資料讀取的效率
2.增加模糊搜索Method
Android和Windows平台其實大同小異,差在資料庫儲存的方式不同而已
(版本請看至頂文)
SQLite的資料儲存型態如下幾點:
- NULL:空值。
- INTEGER:帶符號的整數型態,具體取決有存入數字的範圍大小。
- REAL:浮點數,儲存8-byte IEEE浮點數。
- TEXT:字串型態。
- BLOB:二進制型態。
但實際上,sqlite3也接受如下的數據類型:
- smallint:16 位元的整數。
- interger:32 位元的整數。
- decimal(p,s):p 精確值和 s 大小的十進位整數,精確值p是指全部有幾個數(digits)大小值,s是指小數點後有幾位數。如果沒有特別指定,則系統會設爲 p=5; s=0 。
- float:32位元的浮點數。
- double:64位元的浮點數。
- char(n):n 長度的字串,n不能超過 254。
- varchar(n):長度不固定且其最大長度爲 n 的字串,n不能超過 4000。
- graphic(n):和 char(n) 一樣,不過其單位是兩個字元 double-bytes, n不能超過127。這個形態是爲了支援兩個字元長度的字體,例如中文字。
- vargraphic(n):可變長度且其最大長度爲 n 的雙字元字串,n不能超過 2000。
- date:包含了 年份、月份、日期。
- time:包含了 小時、分鐘、秒。
- timestamp:包含了 年、月、日、時、分、秒、千分之一秒。
先創建一個新的Project,我將其命名為test
場景只留下Main Camera,將紅框這邊的顏色改為黑色(只是為了方便顯示結果)
然後請下載以下這些檔案(SQLite3已包好)
1.SQLite3 Database for Android.unitypackage
Database.cs內的資料庫處理程式碼則是修改雨松大大的這篇文章
下載後引入SQLite3 Database for Android.unitypackage,再將Database.cs放到專案內(test則是我另外存的場景,SQLite3 Database for Android.unitypackage內不會有這個檔案)
先創造一個C# scripts,我將其命名為Test,然後編寫以下程式
using UnityEngine;
using System.Collections;
using Mono.Data.Sqlite;
public class Test : MonoBehaviour
{
Database db;//資料庫物件
string databaseName = "Yang.db";//資料庫名稱
string tableName = "Yu";//資料庫內的資料表名稱
SqliteDataReader reader;//搜尋資料表的資料
string show = "";//要顯示在螢幕上的內容
/* Unity預設的函數執行順序為:Awake -> OnEablen -> Start -> FixedUpdate -> Update -> LateUpdate -> OnGUI -> (結束時繼續往下走,否則回到FixedUpdate) -> OnDisable -> OnDestroy */
void Start ()
{
db = new Database(databaseName);//建立資料庫,同時進行連線,也可改寫成下面被註解的那兩行。由於不同平台所使用的連線語法都不一樣,所以我已經先預設好了,若要修改或得知Windows路徑則到Database.cs內搜尋「Windows端的資料庫存放位置」;Android則因為諸多限制,所以不建議修改。
/*
db = new Database();
db.databaseConnection(databaseName);
*/
db.openDatabaseConnecting();//開啟資料庫
if (db.isTableExists(tableName) == false)//確認是否已有指定的資料表,若沒有則創造該資料表同時插入資料
{
db.createTable(tableName, new string[] { "Name", "Age" }, new string[] { "TEXT", "INTEGER" });//TEXT為SQLite的字串型態,INTEGER為SQLite的整數型態
db.insertInto(tableName, new string[] { "'Yang'", "21" });//資料庫的字串資料必須使用單引號框起來'Yang'
db.insertInto(tableName, new string[] { "'Qing'", "22" });
}
}
void OnGUI()
{
GUI.Label(new Rect(250, 0, 500, 500), show);
if (GUI.Button(new Rect(0, 0, 200, 100), "搜尋Name資料並顯示"))
{
//搜尋和讀取符合的資料
reader = db.searchAccordData(tableName, "Name", "=", "'Yang'");
string[] data = db.readStringData(reader, "Name");
//將讀取到的第一筆資料顯示出來
show = data[0].ToString();
}
if (GUI.Button(new Rect(0, 150, 200, 100), "搜尋Age資料並顯示"))
{
//搜尋和讀取符合的資料
reader = db.searchAccordData(tableName, "Age", ">", "21");
int[] data = db.readIntData(reader, "Age");
//將讀取到的第一筆資料顯示出來
show = data[0].ToString();
}
}
void OnDisable()
{
db.closeDatabaseConnecting();//當該程式碼所放置的物件被銷毀時關閉資料庫連線
}
void OnDestroy()
{
//釋放資料庫
db.releaseDatabaseAllResources();
}
}
然後只要將Test.cs拖到Main Camera身上即可(Database.cs不需要拖到任何物件身上)
按下執行即可成功創建資料庫,且插入、讀取內部資料。
以下是執行結果:
(在Unity上)
(在Windows上,到 Player Settings → Other Settings 將紅框處改為和我一樣)
(在Android手機上,和Windows上一樣選擇.NET 2.0,PlayerSettings.bundleIdentifier則是隨意輸入,其他建議和我一樣)
Database.cs內的方法(Method)已有用中文解釋,若不清楚可以使用這個軟體讀取資料庫後查看程式碼到底做了哪些事。

您好: 我嘗試使用您的方法成功在 Unity 中存取 SQLite 資料庫, 但是在 Build 後執行遊戲,便出現 DllNotFoundException: sqlite3 的訊息, 造成遊戲中無法開啟SQLite資料庫, 請問您有遇過此問題而有方法解決嗎? 感謝~
SQLite沒有正確的包含在Build後的檔案內 如果是APK檔請解壓縮(如同zip那樣解壓縮)查看 如果是Windows的話則在Data資料夾內查看 (一般來說完全按照我的方式和檔案的話,是不會出現那種問題...)
感謝您的回覆~ 我是在windows下, Build 遊戲後,出現2種情況: 1. Build 遊戲後,data/pluins/ 底下是空的,如同您所說SQLite沒有正確的包含在Build後的檔案內,執行遊戲當然找不到sqlites.dll ,嘗試直接將sqlites.dll copy至 data/pluins/ 底下,執行遊戲卻仍然不行,還是說明找不到sqlites.dll 2.幾次Build 遊戲,data/pluins/ 底下終於出現了sqlites.dll 檔案,執行遊戲卻仍然不行,同樣說明找不到sqlites.dll 相當苦惱~ 非常感謝您的教學~
不好意思~ 其實我有2處不同, 1.我的unity是 V5.2.1個人版,非專業版(不知是否有影響) 2.前述程式中,我只將 show = data[0].ToString(); 改為show = data[1].ToString(); 因為data[0] 都出現null 而 data[1] 才有正確顯示 其實在unity中 按下play 是正常的,sqlite可以正常運作,只是Build 後的遊戲卻因找不到sqlite3.dll 而無法運作 ~"~
1.必須使用在Pro版才可正常Build SQLite出來(剛剛在文章開頭重新加入提示了,不好意思) 2.不好意思,我忘記當初有重新編輯並清除過Database.cs的Bug後,忘記去更新雲端硬碟了,麻煩您重新下載一次Database.cs即可。
非常感謝您的回覆與熱心教學! 期待您新的教學作品! 造福更多新手! 感謝~
非常感謝此文章, 很成功地運行SQLite
我想請問一下 為什麼我使用 reader = db.searchFullTable(tableName); 照裡來說應該是資料表全部內容都被讀入進去了 int[] data = db.readIntData(reader, "Age"); string[] data2 = db.readStringData(reader, "Name"); 但是我如果接連的存入到矩陣內 第二個所查詢到的長度就為0 必須要分開來寫才行? reader = db.searchFullTable(tableName); int[] data = db.readIntData(reader, "Age"); reader = db.searchFullTable(tableName); string[] data2 = db.readStringData(reader, "Name");
是的! 因為SqliteDataReader提供的的Read()是將reader從開頭讀到結尾,使其內部的flag在讀取完畢後移動到了結尾,造成要重複讀取時讀不到資料。 要解決的方法只有重新呼叫search並將結果指定給reader (也就是你所說的分開寫)
不好意思 我想再問一個問題 如果我想要Create 一個 table 並且讓他自動編碼 是 使用 AUTO_INCREMENT 嗎? 還是無法設定呢? 因為我試了很多次都會顯示SQL Error
http://www.w3school.com.cn/sql/sql_autoincrement.asp
你好 想請問一下 build出來的遊戲在Android 6.0.1 版本下會DllNotFoundException: sqlite3 而在Anroid 5.x版本的手機執行則正常 有什麼方法嗎?
後來Google到的問題好像跟特定手機型號有關... 我用的是LG Nexus 5 該不會無解吧QQ
由於我沒有Nexus系列的手機可以做測試... 所以根據網路上找到的這兩篇文章,麻煩你先試試看了... http://stackoverflow.com/questions/3645319/why-do-i-get-a-sqlite3-not-found-error-on-a-rooted-nexus-one-when-i-try-to-op http://stackoverflow.com/questions/7877891/sqlite3-not-found
你好,我想請問一下 我假如要計算資料庫內有幾筆資料的話,我該用什麼做計算,要在Database.cs內增加,還是在主程式內新增
兩個方法... 1.直接在Database.cs內新增計算數量的Method。 2.使用searchFullTable讀取全部資料後搭配Get,然後在計算得到的資料量。
上次謝謝您上次幫我解答 我這次在結合另外一個檔案時,會遇到錯誤訊息 Unhandled Exception: System.TypeLoadException: Could not load type 'Mono.Data.Sqlite.SqliteStatement' from assembly 'Mono.Data.Sqlite 我有去查過,很像也有人有遇到過這個訊息,沒有人po出解決辦法 可以麻煩您幫我解答一下嘛!謝謝^^
兩個原因: 1.型態錯誤 你讀寫資料的時候,資料型態和Column型態不合 例如你寫入int型態,可是該Column的型態卻是string 2.找不到指定的DLL檔
感謝你的介紹 我現在要將資料寫進資料庫時,已經確定Table存在了 使用db.insertInto(Table名稱, new string[] {要輸入的資料}); 會出現錯誤訊息 SqliteException: SQLite error no such column: "顯示出我的new string[1]資料" Mono.Data.Sqlite.SQLite3.Prepare (Mono.Data.Sqlite.SqliteConnection cnn, System.String strSql, Mono.Data.Sqlite.SqliteStatement previous, UInt32 timeoutMS, System.String& strRemain) Mono.Data.Sqlite.SqliteCommand.BuildNextCommand () UnityEngine.EventSystems.EventSystem:Update() 我程式碼一筆一筆去看也不懂是哪裡出錯,insertInto()這不會有錯,而是在executeQuery()這邊就錯了。麻煩您幫我解答!謝謝
錯誤訊息指出:no such column 這樣會有三個原因... 1.Column的型態和存入型態不同。 2.假設你的Column只有3個,你卻存了4個Column進去。 3.找不到Column,可能是檔案名稱錯誤之類的,建議用英文+數字的路徑。
不好意思! 我現在又出現了一個問題! 我在window上照你的交法可以成功使用sqlite 但build在平板上會出現 Assets/Database.cs(48,14): error CS0103: The name `File' does not exist in the current context 這樣的錯誤訊息 使用是pro版本了,不知道是哪裡有錯 謝謝您!^_^
找不到檔名File... 確認一下資料庫檔案、資料表名稱是否都正確,錯誤原因是找不到檔案
Build進平板時,會執行 #if UNITY_ANDROID //若是在Android平台 connectString = "URI=file:" + Application.persistentDataPath + "/"; if (!File.Exists(Application.persistentDataPath + "/" + databaseName)) { WWW loadDB = new WWW("jar:file://" + Application.dataPath + "!/assets/" + databaseName); while (!loadDB.isDone) {} File.WriteAllBytes(Application.persistentDataPath + "/" + databaseName, loadDB.bytes); } 這個程式碼吧? 這樣這筆FILE他會從哪裡抓取? 不好意思~我是新手使用 還有很多很多不懂 現在很急需要他可以成功在平板上能夠使用
/data/data/xxx.xxx.xxx/files 其中XXX是你的專案Package名稱 詳情可以到這邊看:http://www.cnblogs.com/murongxiaopifu/p/4199541.html
謝謝您!不好意思又要打擾您一下了 我剛剛又出現了一個錯誤訊息 ArgumentException: The Assembly System.Configuration is referenced by System.Data ('Assets/Plugins/System.Data.dll'). But the dll is not allowed to be included or could not be found. UnityEditor.AssemblyHelper.AddReferencedAssembliesRecurse (System.String assemblyPath, System.Collections.Generic.List`1 alreadyFoundAssemblies, System.String[] allAssemblyPaths, System.String[] foldersToSearch, System.Collections.Generic.Dictionary`2 cache, BuildTarget target) (at C:/buildslave/unity/build/Editor/Mono/AssemblyHelper.cs:146) UnityEditor.AssemblyHelper.AddReferencedAssembliesRecurse (System.String assemblyPath, System.Collections.Generic.List`1 alreadyFoundAssemblies, System.String[] allAssemblyPaths, System.String[] foldersToSearch, System.Collections.Generic.Dictionary`2 cache, BuildTarget target) (at C:/buildslave/unity/build/Editor/Mono/AssemblyHelper.cs:152) UnityEditor.AssemblyHelper.AddReferencedAssembliesRecurse (System.String assemblyPath, System.Collections.Generic.List`1 alreadyFoundAssemblies, System.String[] allAssemblyPaths, System.String[] foldersToSearch, System.Collections.Generic.Dictionary`2 cache, BuildTarget target) (at C:/buildslave/unity/build/Editor/Mono/AssemblyHelper.cs:152) UnityEditor.AssemblyHelper.FindAssembliesReferencedBy (System.String[] paths, System.String[] foldersToSearch, BuildTarget target) (at C:/buildslave/unity/build/Editor/Mono/AssemblyHelper.cs:184) UnityEditor.HostView:OnGUI() 這樣是指Plugins資料夾有錯誤?還是我哪裡是沒有用好的!? 謝謝您^_^
在window上可以成功使用 這樣名稱應該不會有錯吧!? 只是在Building後會有問題 謝謝您!!!!^^
輸出成apk後,將apk副檔名改成zip並解壓縮,查看裡面的資料夾,是否有包含System.Data,因為錯誤訊息是說無法include或找不到System.Data.dll
我解壓縮後 可以找到System.Data.dill 他的位置會位於 E:\Users\User\Desktop\MyGame\M\assets\bin\Data\Managed 這樣可以算是有存在這個apk檔內吧!? 還是他的位於的地方有問題?要移動嗎? 謝謝您!麻煩您為我解答!^_^
檔案沒錯 你有使用我給的範例專案執行過嗎?如果範例專案檔還是不能執行,那就是Android又改了讀寫規則了
我在window上可以順利的使用 執行讀取或寫入都沒有問題 可是放進平板就不行 這樣他改讀寫規則的話 我要如何去更改?更改程式碼還是更改擺放檔案的位置 謝謝您!不好意思一值請教您!^^
不好意思!再請教一下 我發現我的問題在build後,我的db檔很像是沒有寫入apk檔案內 是不能讀取現有的資料庫嗎?一定要先寫再讀? 我有去看你上面給的網址 /data/data/xxx.xxx.xxx/files 其中XXX是你的專案Package名稱 也有加AssetBundle在我的asset內,然後裡面再放入我的db檔 這樣也是會錯誤,我有將apk檔解壓縮後看,裡面依舊沒有我的db檔 我該如何去改善 才能使我的apk檔內有我的db檔,讓他可以讀取到我db檔的內容? 不好意思又要請教您了!謝謝您!^_^
你可以使用Android模擬器,將apk安裝在模擬器內,再搭配「RE管理器」查詢一下程式所給出的路徑,看看該路徑內是否有你的db檔。 還有,db檔是apk安裝完成後再產生的,這樣才能讀寫。 如果是想要事先就寫好,那就是要先將db檔放在StreamingAssets內,安裝完畢後再讀取出來,這部分一樣在這個網站有:http://www.cnblogs.com/murongxiaopifu/p/4199541.html#s1
我想做一個可以新增到資料庫的語法 可是他一直跑出 NullReferenceException: Object reference not set to an instance of an object Users.Start () (at Assets/Scripts/Users.cs:35) 這是我新增的內容 DB.InsertValues("Users", new string[] { "1", "'张三'", "22", "'Zhang3@163.com'" }); 這是我DB的Insert public SqliteDataReader InsertValues(string tableName, string[] values) { //获取数据表中字段数目 int fieldCount = ReadFullTable(tableName).FieldCount; //当插入的数据长度不等于字段数目时引发异常 if (values.Length != fieldCount) { throw new SqliteException("values.Length!=fieldCount"); } string queryString = "INSERT INTO " + tableName + " VALUES (" + values[0]; for (int i = 1; i < values.Length; i++) { queryString += ", " + values[i]; } queryString += " )"; return ExecuteQuery(queryString); }
你的Users.cs第35行有問題 若35行是DB.InsertValues("Users", new string[] { "1", "'张三'", "22", "'Zhang3@163.com'" }); 的話,要麻煩檢查一下DB物件是否是NULL
不好意思,想在請問一下如果使用您的程式想做一個新增的動作該如何使用? 不太明白新增裡面string[] column這個字串是甚麼 還有只要unity執行遊戲就可以將資料儲存進sqlite裡面嗎?
1.string[] column,代表的是你資料表的colume名稱(以Excel來舉例的話就是A、B、C這些) 2.是的,只要你的資料庫還保持連線的狀態,就可以隨時寫入資料。
會使用了~ 謝謝您~ 想在請問一個問題,如果想在現有的表中加入資料列可以該如何使用?
你說的資料列是row嗎? 那就是透過insertInto這個method去新增
db.insertInto(tableName, new string[] { "'YYY'", "800" }); 我寫了這段之後去資料庫看並沒有這段資料耶 一定要重新createTable才可以嗎? 假設我已經擁有現有的資料表了 我想在裡面存放一則資料 一樣是用insertinto嗎?
有確認過table是否存在嗎?你的平台是windows? 或者將你的project傳給我,我看一下
有確認了,是Windows沒錯 請問如何傳給您呢?
你傳到google drive,或者是用HFS後給LINK都可以 可以用悄悄話的方式給我
*****
*****
可以了~ if (db.isTableExists(tableName) !=false) 我把這個if改成!=就可以直接在table裡面加數據了 好像是判斷說這個table已經存在這樣 非常感謝~如果還有需要會再來請教您的!!
剛好最近剛接觸unity跟sqlite來朝聖一下這篇 目前大概有兩個問題: 1.比如搜尋yang名稱的時候,能不能在顯ˋ示名稱之外也顯示當初設定的年齡? 這樣的話該怎麼寫呢? 2.版主好像都是顯示第一條搜尋結果,請問有沒有辦法將"所有"符合搜尋項目的結果都顯示出來呢? 抱歉問題可能有點菜,還請多指教><
1.可以,自己去Database.cs內做修改 2.搜尋結果是回傳所有符合資料的陣列
*****
*****
*****
但是我沒有dll檔的時候,專案會報錯 說程式出錯之類的 找不到那個dll所以不能包裝..
將DLL檔放在專案和Assets同層的地方並編譯試試? 因為這教學文是Unity 4時做的了,那時導成apk時還可以分開包,可能現在不允許了 如果可以的話把DLL放到Assets/Plugins資料夾內打包一次,將出現的錯誤錯誤訊息貼給我看看
*****
*****
*****
*****
*****
*****
好的!那我想問 DB檔要放置在包裝後的哪裡?? connectString = @"Data Source=" + Application.dataPath + "/"; 我遊戲專案的路徑是這個
http://zxxcc0001.pixnet.net/blog/post/243195373-unity---%E5%90%84%E5%B9%B3%E5%8F%B0%E6%AA%94%E6%A1%88%E8%B7%AF%E5%BE%91
*****
嗨~親愛的部落客與同好夥伴們,看到大家在部落格中互動留言,真是太開心啦~ 痞客邦有個追新留言小祕技tip要偷偷告訴你喲! 只要運用簡單的小撇步,在喜愛的部落格文章中,按下【+關注】按鈕,就能在自己的興趣牆上快速追蹤各種最新動態,即時和部落客與同好夥伴們留言互動,還能探索發掘更多你可能喜歡的興趣社群新鮮事喔! >>去看看怎麼運用【+關注】https://goo.gl/xfxB4o 也歡迎大家多多關注痞客邦官方帳號,獲得更多新消息! >>去關注【痞客邦】https://goo.gl/2sEzuL >>去關注【PIXstyleMe】https://goo.gl/PBGd69
嗨~親愛的部落客與同好夥伴們,看到大家在部落格中互動留言,真是太開心啦~ 痞客邦有個追新留言小祕技tip要偷偷告訴你喲! 只要運用簡單的小撇步,在喜愛的部落格文章中,按下【+關注】按鈕,就能在自己的興趣牆上快速追蹤各種最新動態,即時和部落客與同好夥伴們留言互動,還能探索發掘更多你可能喜歡的興趣社群新鮮事喔! >>去看看怎麼運用【+關注】https://goo.gl/xfxB4o 也歡迎大家多多關注痞客邦官方帳號,獲得更多新消息! >>去關注【痞客邦】https://goo.gl/2sEzuL >>去關注【PIXstyleMe】https://goo.gl/PBGd69
嗨~親愛的部落客與同好夥伴們,看到大家在部落格中互動留言,真是太開心啦~ 痞客邦有個追新留言小祕技tip要偷偷告訴你喲! 只要運用簡單的小撇步,在喜愛的部落格文章中,按下【+關注】按鈕,就能在自己的興趣牆上快速追蹤各種最新動態,即時和部落客與同好夥伴們留言互動,還能探索發掘更多你可能喜歡的興趣社群新鮮事喔! >>去看看怎麼運用【+關注】https://goo.gl/xfxB4o 也歡迎大家多多關注痞客邦官方帳號,獲得更多新消息! >>去關注【痞客邦】https://goo.gl/2sEzuL >>去關注【PIXstyleMe】https://goo.gl/PBGd69
請問不是PRO版的話 2018年版本的unity3d 還可以用您說的取巧方式包DLL檔嗎
不好意思,由於我已經很久沒開發Android的應用了,不清楚這個方式是否還可以在Android上使用 在Windows上是沒問題的