Unity3D高級(jí)-Sqlite

SQLite 是一種嵌入式數(shù)據(jù)庫(kù)定拟,它的數(shù)據(jù)庫(kù)就是一個(gè)文件。由于SQLite本身是C寫(xiě)的蹋嵌,而且體積很小,所以葫隙,經(jīng)常被集成到各種應(yīng)用程序中栽烂,甚至在iOS和Android的App中都可以集成。SQLite是一個(gè)進(jìn)程內(nèi)的庫(kù)恋脚,實(shí)現(xiàn)了自給自足的腺办、無(wú)服務(wù)器的、零配置的糟描、事務(wù)性的 SQL 數(shù)據(jù)庫(kù)引擎怀喉。它是一個(gè)零配置的數(shù)據(jù)庫(kù),這意味著您不需要在系統(tǒng)中配置船响,就可以使用躬拢。

特點(diǎn)

不需要一個(gè)單獨(dú)的服務(wù)器進(jìn)程或操作的系統(tǒng)(無(wú)服務(wù)器的)。
SQLite 不需要配置见间,這意味著不需要安裝或管理聊闯。
一個(gè)完整的 SQLite 數(shù)據(jù)庫(kù)是存儲(chǔ)在一個(gè)單一的跨平臺(tái)的磁盤(pán)文件。
SQLite 是非常小的米诉,是輕量級(jí)的菱蔬,完全配置時(shí)小于 400KiB,省略可選功能配置時(shí)小于250KiB史侣。
SQLite 是自給自足的拴泌,這意味著不需要任何外部的依賴(lài)。
SQLite 事務(wù)是完全兼容 ACID 的惊橱,允許從多個(gè)進(jìn)程或線程安全訪問(wèn)蚪腐。
SQLite 支持 SQL92(SQL2)標(biāo)準(zhǔn)的大多數(shù)查詢(xún)語(yǔ)言的功能。


Unity中使用

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

/// <summary>
/// 數(shù)據(jù)庫(kù)管理器
/// </summary>
public class DBManager :MonoBehaviour{

    private static DBManager _instance;
    public static DBManager Instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject go = new GameObject("DBManger");
                _instance = go.AddComponent<DBManager>();
            }
            return _instance;
        }
    }
    //用于建立數(shù)據(jù)庫(kù)連接税朴,保證數(shù)據(jù)流
    SqliteConnection connection;
    //數(shù)據(jù)庫(kù)命令
    SqliteCommand command;
    //數(shù)據(jù)庫(kù)閱讀器
    SqliteDataReader reader;

    private const string dbName = "data";

    void Awake()
    {
        InitDB();

        OpenDB();
    }
    void OnDestroy()
    {
        CloseDB();
    }
    
    //拷貝數(shù)據(jù)庫(kù)到沙盒目錄
    void InitDB()
    {
        Debug.Log("*-> DBManager->Init");
        //判斷是移動(dòng)端
        if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
        {
            string systemDBPath = Application.persistentDataPath + "/data.db";
            // copy data.db from steamingAssetsPath to persistentDataPath
            if (!System.IO.File.Exists(systemDBPath))
            {
                CopyFileFromStreamingAssetsToPersistentDataPath("/data.db");
            }
        }
    }

    void CopyFileFromStreamingAssetsToPersistentDataPath(string relativePath)
    {
        string fileInStreamingAssets = Application.streamingAssetsPath + relativePath;
        string fileInPersistentDataPath = Application.persistentDataPath + relativePath;

        Debug.Log(fileInStreamingAssets + "->"+ fileInPersistentDataPath);

        if (Application.platform == RuntimePlatform.Android)
        {
            WWW fileReader = new WWW(fileInStreamingAssets);
            while (!fileReader.isDone) { }

            //把www加載的數(shù)據(jù)庫(kù)的bytes寫(xiě)入到沙盒的data.db
            FileUtil.WriteFile(fileInPersistentDataPath, fileReader.bytes);
        }
        else
        {
            byte[] content = FileUtil.ReadFile(fileInStreamingAssets);
            FileUtil.WriteFile(fileInPersistentDataPath, content);
        }
    }
    public void OpenDB()
    {
        try
        {
            //指定數(shù)據(jù)庫(kù)路徑削茁,一般放置到StreamingAsset下
            string path = Application.streamingAssetsPath + "/" + dbName + ".db";
            if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
            {
                path = Application.persistentDataPath + "/" + dbName + ".db";
            }

            Debug.Log("dbPath:" + path);
            //新建數(shù)據(jù)庫(kù)連接
            connection = new SqliteConnection(@"Data Source = " + path);
            //打開(kāi)數(shù)據(jù)庫(kù)
            connection.Open();
            Debug.Log("打開(kāi)數(shù)據(jù)庫(kù)");
        }
        catch (Exception ex)
        {
            Debug.Log(ex.ToString());
        }
    }

    public void CloseDB()
    {
        if(connection!=null)
            connection.Close();
        if (command != null)
            command.Dispose();//Dispose用于釋放宙枷,和Close功能一樣
        if (reader != null)
            reader.Close();
        Debug.Log("關(guān)閉數(shù)據(jù)庫(kù)");
    }

    //創(chuàng)建表
    //Activator.CreateInstance(type);//根據(jù)System.Type類(lèi)型去實(shí)例化一個(gè)類(lèi)
    //var fields = type.GetFields();//根據(jù)System.Type類(lèi)型拿到類(lèi)中的字段
    //fields[i].Name//得到單個(gè)字段的名字
    //fields[i].Name//T t:  type.GetField(fields[i].Name).GetValue(t);//得到T類(lèi)型的t中field的值
    //fields[i].Name//T t:  type.GetField(fields[i].Name).SetValue(t,"新的值");//設(shè)置T類(lèi)型的t中field的值
    public void CreateTable<T>()
    {
        var type = typeof(T);
        string sql = "create Table "+type.Name+"(";
        var fields = type.GetFields();
        for (int i = 0; i < fields.Length; i++)
        {
            sql += "[" + fields[i].Name + "] " + CS2DB(fields[i].FieldType)+",";
        }
        sql = sql.TrimEnd(',') + ")";
        Excute(sql);
    }

    public void Insert<T>(T t)
    {
        var type = typeof(T);
        string sql = "insert into " + type.Name + " values (";

        var fields = type.GetFields();
        foreach (var field in fields)
        {
            //通過(guò)反射得到對(duì)象中的值
            sql += "'" + type.GetField(field.Name).GetValue(t) + "',";
        }
        sql = sql.TrimEnd(',') + ");";

        Excute(sql);
    }
    //插入語(yǔ)句
    //--insert into users values("小新",28,'男','371452646566256456',1235123123);
    public void InsertInto(string tbName,params object[] objs)
    {
        string sql = "insert into " + tbName + " values (";
        foreach (var item in objs)
        {
            sql += "'"+ item + "',";
        }
        //sql=sql.Substring(0, sql.Length - 1);
        sql=sql.TrimEnd(',')+ ");";

        Excute(sql);
    }
    //刪除語(yǔ)句
    public void DeleteAnd(string tbName,params object[] objs)
    {
        string sql = "delete from " + tbName + " where (";
        for (int i = 0; i < objs.Length-1; i+=2)
        {
            sql += objs[i] + "='" + objs[i + 1] +"' and ";
        }
        sql=sql.Substring(0, sql.Length - 4)+ ");";
        Excute(sql);

    }
    //修改語(yǔ)句
    //--update users set age = 18 where name = '小史'and cardid isnull;
    public void UpdateAnd(string tbName, object[] colums,params object[] conditions)
    {
        string sql = "update "+tbName+" set ";
        for (int i = 0; i < colums.Length-1; i+=2)
        {
            sql += colums[i] + "='" + colums[i + 1] + "',";
        }
        sql = sql.TrimEnd(',') + " where (";
        for (int i = 0; i < conditions.Length-1; i+=2)
        {
            sql += conditions[i] + "='" + conditions[i + 1]+"' and ";
        }
        sql = sql.Substring(0, sql.Length - 4) + ");";
        Excute(sql);
    }
    //查詢(xún)>字典
    public List<Dictionary<string, string>> Select(string tbName)
    {
        string sql = "select * from " + tbName;
        Excute(sql);
        List<Dictionary<string, string>> result = new List<Dictionary<string, string>>();
        while(reader.Read())
        {
            var dic = new Dictionary<string, string>();
            for (int i = 0; i < reader.FieldCount; i++)
            {
                dic.Add(reader.GetName(i), reader.GetValue(i).ToString());
            }
            result.Add(dic);
        }
        return result;
    }

    /// <summary>
    /// 泛型約束
    /// class :引用類(lèi)型
    /// struct:值類(lèi)型
    /// 接口和抽象類(lèi)
    /// 普通類(lèi)
    /// new():無(wú)參構(gòu)造,(必須是最后一個(gè)約束)
    /// </summary>
    //查詢(xún):泛型實(shí)體類(lèi)(復(fù)用性高,靈活)
    public List<T> Select<T>() where T: new()
    {
        var type = typeof(T);
        string sql = "select * from " + type.Name;
        Excute(sql);

        List<T> result = new List<T>();
        var fields = type.GetFields();
        while (reader.Read())//讀取下一行數(shù)據(jù)
        {
            T t = new T();//使用new() 實(shí)例化T
            for (int i = 0; i < reader.FieldCount; i++)
            {
                string key = reader.GetName(i);//獲取數(shù)據(jù)庫(kù)指定列的key
                object value = reader.GetValue(i);//獲取數(shù)據(jù)庫(kù)指定列的值
                Debug.Log(key + ":" + value);
                type.GetField(key).SetValue(t, value);//使用反射給T類(lèi)型t賦值
            }
            result.Add(t);
        }
        return result;
    }

    /// <summary>
    /// 通過(guò)Id查詢(xún)數(shù)據(jù)
    /// </summary>
    public T SelectById<T>(string id) where T:new()
    {
        Type type = typeof(T);
        string sql = "select * from " + type.Name + " where id='" + id+"'";
        Excute(sql);

        T t = new T();
        reader.Read();
        var count = reader.FieldCount;
        for (int i = 0; i < count; i++)
        {
            string key = reader.GetName(i);
            object value = reader.GetValue(i);
            type.GetField(key).SetValue(t, value);
        }
        return t;
    }

    void Excute(string sql)
    {
        Debug.LogWarning(sql);
        //創(chuàng)建數(shù)據(jù)庫(kù)連接命令
        command = connection.CreateCommand();
        //設(shè)置命令語(yǔ)句
        command.CommandText = sql;
        //執(zhí)行命令
        reader = command.ExecuteReader();
    }

    string CS2DB(Type type)
    {
        string result = "Text";
        if(type==typeof(Int32))
        {
            result = "Int";
        }
        else if (type == typeof(String))
        {
            result = "Text";
        }
        else if (type == typeof(Single))
        {
            result = "FLOAT";
        }
        else if (type == typeof(Boolean))
        {
            result = "Bool";
        }
        return result;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末茧跋,一起剝皮案震驚了整個(gè)濱河市慰丛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘾杭,老刑警劉巖诅病,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異粥烁,居然都是意外死亡贤笆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)讨阻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)芥永,“玉大人,你說(shuō)我怎么就攤上這事钝吮÷窠В” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵奇瘦,是天一觀的道長(zhǎng)棘催。 經(jīng)常有香客問(wèn)我,道長(zhǎng)耳标,這世上最難降的妖魔是什么醇坝? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮次坡,結(jié)果婚禮上呼猪,老公的妹妹穿的比我還像新娘。我一直安慰自己砸琅,他們只是感情好郑叠,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著明棍,像睡著了一般乡革。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上摊腋,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天沸版,我揣著相機(jī)與錄音,去河邊找鬼兴蒸。 笑死视粮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的橙凳。 我是一名探鬼主播蕾殴,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼笑撞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了钓觉?” 一聲冷哼從身側(cè)響起茴肥,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荡灾,沒(méi)想到半個(gè)月后瓤狐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡批幌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年础锐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荧缘。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡皆警,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出截粗,到底是詐尸還是另有隱情信姓,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布桐愉,位于F島的核電站财破,受9級(jí)特大地震影響掰派,放射性物質(zhì)發(fā)生泄漏从诲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一靡羡、第九天 我趴在偏房一處隱蔽的房頂上張望系洛。 院中可真熱鬧,春花似錦略步、人聲如沸描扯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)绽诚。三九已至,卻和暖如春杭煎,著一層夾襖步出監(jiān)牢的瞬間恩够,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工羡铲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蜂桶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓也切,卻偏偏與公主長(zhǎng)得像扑媚,于是被迫代替她去往敵國(guó)和親腰湾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容