[Unity]SQLite数据库操作

[Unity]技术学习路线图(长期更新)

项目开发的时候,经常会遇到的一种需求,数据存储

离线缓存的数据类型很多,大致分成两类

  • 字符串文本数据
  • 多媒体数据

字符串数据的类型只有字符串,但是结构有很多:

  • xml
  • json
  • md5
  • base64
  • 普通字符串

多媒体数据的类型:

  • 图片(jpg,png,gif...)
  • 音频(mp3,aif...)
  • 视频(mp4,mpv)

通常用数据库来存储字符串文本类型的数据,但是需要注意的是数据库同时也能存储多媒体类型的数据


关系数据库
在一个给定的应用领域中,所有实体及实体之间联系的集合构成一个关系数据库。
目前主流的关系数据库有oracle、db2、sqlserver、sybase、mysql等。

在Unity中打开数据库函数

    private string GetDBPath(string name)
    {
        return Application.persistentDataPath + "/" + name + ".sqlite";
    }

    /// <summary>
    /// 就是用来存储程序与数据库链接的对象
    /// </summary>
    private SqliteConnection connection = null;
    private void OpenDataBase()
    {
        //获取一个数据库文件的路径
        string path = GetDBPath ("xiaohao");
        string c = "Data Source=" + path;
        //需要通过数据库文件磁盘路径进行初始化
        connection = new SqliteConnection (c);
        //打开数据库
        connection.Open();
    }

CRUD


创建表格SQL

create table lo_human(human_id integer,human_name text,human_age integer);

C#函数调用创建表格SQL

    private void CreateObject()
    {
        //在一个数据库链接对象上创建一个命令对象
        SqliteCommand command = new SqliteCommand(connection);

        //给命令对象添加SQL语句
        command.CommandText = "create table if not exists lo_human(human_id integer,human_name text,human_age integer);";

        //执行命令
        command.ExecuteNonQuery();
    }

添加数据

insert into lo_human(human_id,human_name,human_age) values(1,'xiaohao',36);

C#函数调用添加数据SQL

    private void InsertObject()
    {
        //在一个数据库链接对象上创建一个命令对象
        SqliteCommand command = new SqliteCommand (connection);

        //给命令对象添加SQL语句
        command.CommandText = "insert into lo_human(human_id,human_name,human_age) values(1,'xiaohao',36);";

        //执行命令
        command.ExecuteNonQuery ();
    }

更新数据

update lo_human set human_name='cuiyayun' where human_id=2;

C#函数调用更新数据SQL

    private void UpdateObject()
    {
        //在一个数据库链接对象上创建一个命令对象
        SqliteCommand command = new SqliteCommand (connection);
        
        //给命令对象添加SQL语句
        command.CommandText = "update lo_human set human_name='cuiyayun' where human_id=3;";
        
        //执行命令
        command.ExecuteNonQuery ();
    }

删除数据

delete from lo_human where humanid=1;

C#函数调用删除数据SQL

    private void DeleteObject()
    {
        //在一个数据库链接对象上创建一个命令对象
        SqliteCommand command = new SqliteCommand (connection);
        
        //给命令对象添加SQL语句
        command.CommandText = "delete from lo_human where human_id=1;";
        
        //执行命令
        command.ExecuteNonQuery ();
    }

查询数据

select * from lo_human where human_id>15 order by human_id desc;

C#函数调用查询数据SQL

    private void SelectObject()
    {
        //在一个数据库链接对象上创建一个命令对象
        SqliteCommand command = new SqliteCommand (connection);
        
        //给命令对象添加SQL语句
        command.CommandText = "select * from lo_human where human_id>15 order by human_id desc;";

        //数据读取器
        SqliteDataReader reader = command.ExecuteReader();

        //判读是否可以读取下一行数据,如果可以的话就获取数据
        while (reader.Read())
        {
            //在循环体里,已经确定是哪行数据.
            Debug.Log(reader ["human_name"]);
        }
    }

高级用法

通过使用C#语言的反射机制实现工具类SQLiteTools

    [AttributeUsage(AttributeTargets.Property)]
    public class SQLFieldAttribute:Attribute
    {
        public string Name{ set; get;}
        public string Type{ set; get;}
        public bool IsNotNull{ set; get;}
        public bool AutoIncrement{set;get;}
        public bool IsPrimaryKey{set;get;}
        public string Default{ set; get;}
        public bool IsUnique{set;get;}
    }

    [AttributeUsage(AttributeTargets.Class)]
    public class SQLTableAttribute:Attribute
    {
        public string Name{set;get;}
    }
    
    /// <summary>
    /// 测试功能用到的类
    /// </summary>
    //创建TestClass附件的特性对象SQLTable,并且将该特性对象的属性Name赋值为"test_class"
    [SQLTable(Name="test_class")]
    public class TestClass
    {

        //创建test_id属性附件的特性对象SQLField,并且将该特性对象的属性Name、Type、AutoIncrement、IsNotNull、IsPrimaryKey进行赋值
        [SQLField(Name="test_id",Type="integer",AutoIncrement=true,IsNotNull=true,IsPrimaryKey=true)]
        public int      test_id{set;get;}

        [SQLField(Name="test_name",Type="text")]
        public string   test_name{set;get;}

        [SQLField(Name="test_age",Type="integer")]
        public int      test_age{ set; get;}

        public TestClass(){}
    }

LOSQLiteTools.cs实现具体的功能
获取表格名称函数

        /// <summary>
        /// 获取表格的名称
        /// </summary>
        /// <returns>The table name.</returns>
        private static string GetTableName(Type item)
        {
            //获取到特性类型
            Type att_type = typeof(SQLTableAttribute);

            //获取参数type对应的特性对象
            Attribute a = Attribute.GetCustomAttribute(item,att_type);

            if (a == null) {
                return null;
            }

            //因为在Attribute.Get函数里的最后一个参数已经指定了
            //特性的类型是SQLTableAttribute,所以可以显式转换
            SQLTableAttribute sa = (SQLTableAttribute)a;

            //将特性对象的Name属性返回
            return sa.Name;
        }

获取属性姓名函数

        /// <summary>
        /// 获取属性在Field中的名字
        /// </summary>
        private static string GetFieldName(PropertyInfo item)
        {
            Type att_type = typeof(SQLFieldAttribute);

            Attribute a = Attribute.GetCustomAttribute (item, att_type);

            if (a == null) {
                return null;
            }

            SQLFieldAttribute sfa = (SQLFieldAttribute)a;

            return sfa.Name;
        }

获取属性类型函数

        /// <summary>
        /// 获取属性在Field中的类型
        /// </summary>
        private static string GetFieldType(PropertyInfo item)
        {
            Type att_type = typeof(SQLFieldAttribute);

            Attribute a = Attribute.GetCustomAttribute (item, att_type);

            if (a == null) {
                return null;
            }

            SQLFieldAttribute sfa = (SQLFieldAttribute)a;

            return sfa.Type;
        }

获取属性区域字符串函数

        /// <summary>
        /// 获取创建表格时的Field字符串
        /// </summary>
        private static string GetFieldString(PropertyInfo item)
        {
            Type att_type = typeof(SQLFieldAttribute);
            Attribute a = Attribute.GetCustomAttribute (item, att_type);

            if (a == null) {
                return null;
            }

            SQLFieldAttribute sfa = (SQLFieldAttribute)a;

            string sql = "";
            sql += sfa.Name + " ";
            sql += sfa.Type + " ";

            if (sfa.IsPrimaryKey) {
                sql += "primary key" + " ";
            }
            if (sfa.AutoIncrement) {
                sql += "autoincrement" + " ";
            }
            if (sfa.IsNotNull) {
                sql += "not null" + " ";
            }
            if (sfa.IsUnique) {
                sql += "unique" + " ";
            }
            if (sfa.Default != null) {
                sql += "default " + sfa.Default;
            }

            return sql;
        }

创建表格函数

        /// <summary>
        /// 通过实体类型创建数据库表格
        /// </summary>
        public static void CreateTable(Type type)
        {
            //获取一个类型的所有属性
            PropertyInfo[] p_list = type.GetProperties();

            //获取Table的名字
            string table_name = GetTableName(type);

            //获取Table的列名字符串
            string field_list = "(";

            foreach (PropertyInfo item in p_list) 
            {
                //对应的属性区域
                field_list += GetFieldString(item) + ",";
            }

            //删除最后一个,
            field_list = field_list.Substring (0, field_list.Length - 1);

            field_list += ")";

            //开始构造sql命令
            string sql = "create table if not exists ";
            sql += table_name + field_list + ";";

            Debug.Log (sql);

            SqliteCommand command = new SqliteCommand (connection);

            command.CommandText = sql;

            command.ExecuteNonQuery ();
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容