1. 程式人生 > >關於unity專案中使用sqlite

關於unity專案中使用sqlite

一:準備,Mono.Data.Sqlite.dll,System.Data.dll,sqlite3.dll(X86和X86_64),這些dll檔案是必須的。將他們放到Plugins資料夾下即可。dll缺一不可,否則打包出來會有問題。然後需要將API Compatibility Level切換到.NET 2.0 。

二:在網上找了一個連線和讀取的指令碼:

using UnityEngine;
using System.Data;
using System;
using System.Collections;
using Mono.Data.Sqlite;

public class DbAccess

{

    private SqliteConnection dbConnection;

    private SqliteCommand dbCommand;

    private SqliteDataReader reader;

    public DbAccess (string connectionString)

    {

        OpenDB (connectionString);

    }
    public DbAccess ()
    {

    }

    /// <summary>
    /// 開啟資料庫
    /// </summary>
    /// <param name="connectionString">Connection string.</param>
    public void OpenDB (string connectionString)

    {
        try
        {
            dbConnection = new SqliteConnection (connectionString);

            dbConnection.Open ();

            Debug.Log ("Connected to db");
        }
        catch(Exception e)
        {
            string temp1 = e.ToString();
            Debug.Log(temp1);
        }

    }

    /// <summary>
    /// 關閉資料庫
    /// </summary>
    public void CloseSqlConnection ()

    {

        if (dbCommand != null) {

            dbCommand.Dispose ();

        }

        dbCommand = null;

        if (reader != null) {

            reader.Dispose ();

        }

        reader = null;

        if (dbConnection != null) {

            dbConnection.Close ();

        }

        dbConnection = null;

        Debug.Log ("Disconnected from db.");

    }

    /// <summary>
    /// 執行sql語句
    /// </summary>
    /// <returns>The query.</returns>
    /// <param name="sqlQuery">查詢語句.</param>
    public SqliteDataReader ExecuteQuery (string sqlQuery)

    {

        Debug.Log ("sql="+sqlQuery);
        dbCommand = dbConnection.CreateCommand ();

        dbCommand.CommandText = sqlQuery;

        reader = dbCommand.ExecuteReader ();

        return reader;

    }

    /// <summary>
    /// 查詢整個table的資料
    /// </summary>
    /// <returns>The full table.</returns>
    /// <param name="tableName">表名.</param>
    public SqliteDataReader ReadFullTable (string tableName)

    {

        string query = "SELECT * FROM " + tableName;

        return ExecuteQuery (query);

    }

    /// <summary>
    /// 插入資料
    /// </summary>
    /// <returns>The into.</returns>
    /// <param name="tableName">表名</param>
    /// <param name="values">需要插入的欄位內容,注意字串需要新增單引號 如 ‘name’</param>
    public SqliteDataReader InsertInto (string tableName, string[] values)

    {

        string query = "INSERT INTO " + tableName + " VALUES (" + values[0];

        for (int i = 1; i < values.Length; ++i) {

            query += ", " + values[i];

        }

        query += ")";


        return ExecuteQuery (query);

    }

    /// <summary>
    /// 更新table內容
    /// </summary>
    /// <returns>The into.</returns>
    /// <param name="tableName">Table 名稱.</param>
    /// <param name="cols">需要更新的欄位名稱陣列.</param>
    /// <param name="colsvalues">需要更新的欄位對應的值.</param>
    /// <param name="selectkey">更新依據的欄位.</param>
    /// <param name="selectvalue">更新依據欄位對應的值</param>
    public SqliteDataReader UpdateInto (string tableName, string []cols,string []colsvalues,string selectkey,string selectvalue)
    {

        string query = "UPDATE "+tableName+" SET "+cols[0]+" = "+colsvalues[0];

        for (int i = 1; i < colsvalues.Length; ++i) {

            query += ", " +cols[i]+" ="+ colsvalues[i];
        }

        query += " WHERE "+selectkey+" = "+selectvalue+" ";

        return ExecuteQuery (query);
    }

    /// <summary>
    /// 根據刪除條件,刪除對應的資料
    /// </summary>
    /// <param name="tableName">Table 名稱.</param>
    /// <param name="cols">欄位陣列.</param>
    /// <param name="colsvalues">欄位陣列對應的值.</param>
    public SqliteDataReader Delete(string tableName,string []cols,string []colsvalues)
    {
        string query = "DELETE FROM "+tableName + " WHERE " +cols[0] +" = " + colsvalues[0];

        for (int i = 1; i < colsvalues.Length; ++i) {

            query += " or " +cols[i]+" = "+ colsvalues[i];
        }

        return ExecuteQuery (query);
    }

    /// <summary>
    /// 插入資料,只插入部分欄位的資料
    /// </summary>
    /// <returns>The into specific.</returns>
    /// <param name="tableName">Table 名稱.</param>
    /// <param name="cols">需要插入的欄位陣列.</param>
    /// <param name="values">需要插入的欄位陣列對應的值.</param>
    public SqliteDataReader InsertIntoSpecific (string tableName, string[] cols, string[] values)

    {

        if (cols.Length != values.Length) {

            throw new SqliteException ("columns.Length != values.Length");

        }

        string query = "INSERT INTO " + tableName + "(" + cols[0];

        for (int i = 1; i < cols.Length; ++i) {

            query += ", " + cols[i];

        }

        query += ") VALUES (" + values[0];

        for (int i = 1; i < values.Length; ++i) {

            query += ", " + values[i];

        }

        query += ")";

        return ExecuteQuery (query);

    }
    /// <summary>
    /// 根據表名,刪除該表的全部資料
    /// </summary>
    /// <returns>The contents.</returns>
    /// <param name="tableName">Table name.</param>
    public SqliteDataReader DeleteContents (string tableName)

    {

        string query = "DELETE FROM " + tableName;

        return ExecuteQuery (query);

    }

    /// <summary>
    /// 建立一個數據表
    /// </summary>
    /// <returns>The table.</returns>
    /// <param name="name">Name.</param>
    /// <param name="col">Col.</param>
    /// <param name="colType">Col type.</param>
    public SqliteDataReader CreateTable (string name, string[] col, string[] colType)

    {

        if (col.Length != colType.Length) {

            throw new SqliteException ("columns.Length != colType.Length");

        }

        string query = "CREATE TABLE " + name + " (" + col[0] + " " + colType[0];

        for (int i = 1; i < col.Length; ++i) {

            query += ", " + col[i] + " " + colType[i];

        }

        query += ")";

        return ExecuteQuery (query);

    }

    /// <summary>
    /// 根據條件篩選資料
    /// </summary>
    /// <returns>The where.</returns>
    /// <param name="tableName">Table name.</param>
    /// <param name="items">需要篩選的欄位.</param>
    /// <param name="col">篩選條件的健.</param>
    /// <param name="operation">篩選符號,如 >,<,= </param>.</param>
    /// <param name="values">篩選條件的值.</param>
    public SqliteDataReader SelectWhere (string tableName, string[] items, string[] col, string[] operation, string[] values)

    {

        if (col.Length != operation.Length || operation.Length != values.Length) {

            throw new SqliteException ("col.Length != operation.Length != values.Length");

        }

        string query = "SELECT " + items[0];

        for (int i = 1; i < items.Length; ++i) {

            query += ", " + items[i];

        }

        query += " FROM " + tableName + " WHERE " + col[0] + operation[0] + "'" + values[0] + "' ";

        for (int i = 1; i < col.Length; ++i) {

            query += " AND " + col[i] + operation[i] + "'" + values[0] + "' ";

        }

        return ExecuteQuery (query);

    }

}

三:然後將sqlite的資料放到了StreamingAsset檔案下,然後程式一啟動,會將資料拷到PersistentPath目錄下,防止檔案丟失。

當連線資料庫的時候,會從工程目錄下找這個檔案,如果沒有就會從沙盒路徑下拷過來,然後進去讀取。因為sqlite檔案是db結尾的,所以不能用Resources載入。 部分程式碼如下

void Awake(){

CopyFile(Application.streamingAssetsPath + dbName, Application.persistentDataPath + dbName);

/// <summary>
    /// 拷貝檔案
    /// </summary>
    /// <param name="sourcePath"></param>
    /// <param name="distPath"></param>
    private void CopyFile(string sourcePath,string distPath) {
        if (!System.IO.File.Exists(distPath)){
            if (System.IO.File.Exists(sourcePath)) {
                System.IO.File.Copy(sourcePath, distPath);
            }
        }
    }

 /// <summary>
    /// 連線資料庫,請進行讀取資料
    /// </summary>
    private void ConnectSqllite() {
       
        dbPath = getPath();
 
        if (!System.IO.File.Exists(dbPath)) {
            CopyFile(Application.persistentDataPath + dbName, dbPath);
            if (!System.IO.File.Exists(dbPath)) {
                JT_MessageBox.ShowMessageBox(MessageBoxStyle.OnlyOK, "提示訊息", "讀取配置檔案失敗(配置檔案丟失或損壞,請聯絡管理員)");
                return;
            }
            db = new DbAccess("data source=" + dbPath);
        }
        else {
            db = new DbAccess("data source=" + dbPath);
        }

        QueryAllData();
        db.CloseSqlConnection();
    }


    /// <summary>
    /// 讀取配置檔案,將資料存入  textConfigDic字典中
    /// </summary>
    public void QueryAllData() {
        SqliteDataReader reader = db.ReadFullTable("systeminfo1");
        int count = 0;
        while (reader.Read()) {
            TextConfig tc = new TextConfig();

            tc.Id = int.Parse(reader["id"].ToString());
            tc.Name = reader["name"].ToString();
            tc.Meno = reader["meno"].ToString();
            tc.VideoURL = reader["video"].ToString();
            tc.SoundURL = reader["sound"].ToString();
            tc.Isvideo = int.Parse(reader["isvideo"].ToString());
            tc.Createdate = reader["createdate"].ToString();
            textConfigDic.Add(count, tc);

            //Debug.Log ("name=" + reader ["name"] + ",age=" + reader ["age"] + ",sex=" + reader ["sex"] + ",adress=" + reader ["adress"]);
            count++;
        }
    }

      /// <summary>
      /// 配置檔案目錄
      /// </summary>
      /// <returns></returns>
    string getPath() {
        string path = Application.dataPath + "/" + dbName;

        return path;
    }
最後打包出來就OK了。

最後總結一下:主要在於dll檔案,這個花了很長時間。PC條件下,X86,X86_64兩個都要要,否則,打包出來可能會有問題。其他的基本沒什麼。

其實我個人還是喜歡Json。可能是用的多吧,輕巧方便,雖然易讀性差點。

有興趣的可以加我的個人學習交流群(小眾群,沒人說話的,哈哈):195118593 

下面貼幾個講使用sqlitede 我覺得比較好的文章: