@[TOC]数据持久化存储

八.数据持久化存储(下)

3.JSON

语法:大括号:写键值对,键和值之间用冒号分隔,键值对之间用逗号分隔,类似字典中括号:写数据,类似数组// json的注释 /* json的注释 */ { “name”: “xiaoming”, “age”: 10, “gender”: ‘男’ “pet”: { “name”: “hashiqi”, “age”: 3 } } // 另一段json { “name”: “诺克萨斯之手”, “hp”: 582.24, “attack”: 55.88, “skills”: [{ “name”: “被动技能-出血” },{ “name”: “Q技能-大杀四方”, “cd”: [9, 8, 7, 6, 5], “mp”: [30, 30, 30, 30, 30] },{ “name”: “W技能-致残打击”, “cd”: [9, 8, 7, 6, 5], “mp”: [30, 30, 30, 30, 30] },{ “name”: “E技能-无情铁手”, “cd”: [24, 21, 18, 15, 12] },{ “name”: “R技能-诺克萨斯断头台”, “cd”: [120, 100, 80], “mp”: [100, 100, 0] }] } Unity使用的是 .net 2.0,没有对Json的支持,需要用第三方库System.Json(便于Json生成)LitJson(便于Json解析)System.Json 中的类JsonArray:数组JsonObject:键值对JsonValue:具体的值,可以是一个数字,一个字符串等,也可以是一个JsonArray或JsonObjectLitJson对象转Json:JsonMapper.ToJson(T model)Json转对象:JsonMapper.ToObject(string jsonString)Project文件夹中建立Plugins文件夹,用于存放第三方库
Model.cspublic class Player { public string name; public int age; public char gender; public Dog pet; } public class Dog { public string name; public int age; public char gender; }

JSONOperation.cs

using LitJSON; // 实例化一个对象 Player player = new Player(); // 输入对象的信息 player.name = “xiaoming”; … // 将Player的信息生成一个json string json = JsonMapper.ToJson(player); PlayerPrefs.SetString(“json”, json); // 根据一个Json字符串解析成模型 string json = PlayerPrefs.GetString(“json”); Player player = JsonMapper.ToObject(json); JsonUtility 类Unity集成的用来解析生成json的类,用法和LitJson一模一样,效率完胜LitJson模型中嵌套的类需要添加特性[System.Serializable]
Model.cspublic class Player { public string name; public int age; public char gender; public Dog pet; } [System.Serializable] public class Dog { public string name; public int age; public char gender; }

JsonUtility.cs

// 模型转Json string json = JsonUtility.ToJson(player); // Json转模型 Player player = JsonUtility.FromJson(json);

JsonUtility 中无法存 List 和 Dictionary<Tkey, Tvalue> 的解决办法:

List:使用一个类来包含Listpublic class PersonModel : ISerializationCallbackReceiver { public List person; public PersonModel() { person = new List(); } } [Serializable] public class Person { public string name; public int age; public Dog[] dogs; public Person() { dogs = new Dog[2]; } } [Serializable] public class Dog { public string name; public int age; public Gender gender; } public enum Gender { male, female } Dictionary<Tkey, Tvalue>:使用接口ISerializationCallbackReceiverpublic class PersonModel : ISerializationCallbackReceiver { [SerializeField] List keys; [SerializeField] List values; public Dictionary<int, Person> personList; public PersonModel() { personList = new Dictionary<int, Person>(); } // 接口的实现方法,解序列化 public void OnAfterDeserialize() { var count = Math.Min(keys.Count, values.Count); personList = new Dictionary<int, Person>(count); for (var i = 0; i < count; ++i) { personList.Add(keys[i], values[i]); } } // 接口的实现方法,序列化 public void OnBeforeSerialize() { keys = new List(personList.Keys); values = new List(personList.Values); } }

JsonObject插件

JsonUtility转对象的时候,如果对象包含子类,是无法转换到子类的,这时候需要使用JsonObject在AssetStore下载JsonObject插件,并导入到Unity中使用代码解析Json字符串,代码实例:private List itemList = new List(); /// /// 解析物品Json /// public void ParseItemJson(string itemsJson) { JSONObject j = new JSONObject(itemsJson); foreach (JSONObject temp in j.list) { int id = (int)temp[“id”].n; string name = temp[“name”].str; Item.ItemType type = (Item.ItemType)System.Enum.Parse(typeof(Item.ItemType), temp[“type”].str); Item item = null; switch (type) { case Item.Item

4.数据库

4.1 基础知识

数据库分类本地数据库Sqlite 轻便网络数据库OracleSQL ServerMySQLDB2SqliteManager 可视化管理工具Unity支持的数据库后缀名 .sqlite .db数据库中数据的存储格式表格字段(键),不会重复的键称为主键,主键最多1个,可以没有值

4.2 SQL语句

操作语句备注建表CREATE TABLE 表名 (键 类型, 键 类型, …);建表改进CREATE TABLE IF NOT EXISTS 表名 (键 类型, 键 类型, …);只有不存在此表的时候才添加,避免报异常给表格中所有的字段赋值INSERT INTO 表名 VALUES (值,值,值,值);有多少键写多少值给部分字段赋值INSERT INTO 表名 (键,键,键,…) VALUES (值,值,值,…);键的顺序可以不和建表的时候一样,如果表中有NOT NULL的字段但是没有赋值,会报错条件语句WHERE 条件> >= < <= = != AND OR NOT/! + - * / %从表中删除所有的数据DELETE FROM 表名;从表中删除满足条件的数据DELETE FROM 表名 WHERE 条件;从表中修改全部的数据UPDATE 表名 SET 键=值, 键=值, …;从表中修改满足条件的数据UPDATE 表名 SET 键=值, 键=值, … WHERE 条件;查询表中所有的数据的所有字段值SELECT * FROM 表名;查询所有满足条件的数据的所有字段值SELECT * FROM 表名 WHERE 条件;查询所有满足条件的数据的指定字段值SELECT 字段, 字段, … FROM 表名;按查询时字段的顺序显示查询结果排序SELECT * FROM 表名 WHERE 条件 ORDER BY 键 (ASC/DESC), 键 (ASC/DESC), 键 (ASC/DESC), …;ASC 升序 DESC 降序,默认按照主键升序,默认升序所以ASC可以省略SQL语句不区分大小写,表名和键是区分大小写的每一个键都可以有修饰,修饰语句放到类型后面
常用修饰符:PRIMARY KEY:主键NOT NULL:非空类型类型可以不写,默认是TEXT类型// 需求:Person // 字段:姓名(主键),年龄,性别 // 建表 CREATE TABLE Person (name TEXT PRIMARY KEY NOT NULL, age INTEGER, gender); CREATE TABLE IF NOT EXISTS Person (name TEXT PRIMARY KEY NOT NULL, age INTEGER, gender); // 增 INSERT INTO Person VALUES (‘小明’, 10, ‘男’); INSERT INTO Person (name, age) VALUES (‘小红’, 12); // 删 DELETE FROM Person WHERE age > 100 AND age < 20000; DELETE FROM Person WHERE age % 2 = 1; // 改 UPDATE Person SET gender = ‘不知道’; UPDATE Person SET gender = ‘知道’ WHERE age > 100; // 查 SELECT * FROM Person WHERE age > 100 ORDER BY gender DESC;

4.3 代码使用SQL语句

需要用到的动态链接库Sqlite3.dllMono.Data.Sqlite.dllSystem.Data.dllWindow:\Unity\Editor\Data\Mono\lib\mono\2.0\MacOS:/Application/Unity/Unity.app/contents/Mono/lib/mono/2.0使用到的类类描述SqliteConnection与数据库的连接对象SqliteCommand执行SQL语句的对象SqliteDataReader读取数据的对象SqliteConnection的方法方法作用SqliteConnection(path);构造方法,若路径下有数据库文件则建立连接,若没有数据库则新建数据库文件SqliteCommand CreateCommand();创建操作指令对象Open();打开数据库Close();关闭数据库SqliteCommand的方法方法作用int ExecuteNonQuery();执行一个非查询语句,返回有多少行数据收到影响object ExecuteScalar();执行一个查询语句,返回查询到的数据中的第一行第一列SqliteDataReader ExecuteReader();执行一个查询语句,返回一个SqliteDataReaderSqliteDataReader的属性与方法
使用SqliteDataReader之后要关闭它,否则被视为上次的查询操作还没完成,无法再设置CommandText属性与方法作用bool Read();类似于索引器的MoveNext(),读取下一个,返回是否有数据FieldCount键的数量string GetName(int index);通过键的下标,获取键的名称object GetValue(int index);通过键的下标,获取键的值Close();SqliteDataReader的方法,关闭SqliteDataReaderusing Mono.Data.Sqlite; // 类 // 与数据库的连接对象 SqliteConnection _connection; // 执行SQL语句的对象 SqliteCommand _command; // 读取数据的对象 SqliteDataReader _reader; // 1. 建立与数据库的连接 // 如果路径下没有数据库,系统会自动帮我们新建一个数据库,如果路径下有数据库,则建立连接 // 1.1 拼接一个数据库的路径 string path = "Data Source = " + Application.dataPath + “/Database/myDatabase.sqlite”; // 1.2 建立与数据库的连接 _connection = new SqliteConnection(path); // 1.3 创建操作指令对象 _command = _connection.CreateCommand(); // 1.4 打开数据库 // 有打开数据库,就需要有关闭数据库,如果程序结束后数据库没关,数据库会锁上自己,再解锁很麻烦 _connection.Open(); // 2. 建表 // 2.1 写SQL语句 string sql = @“CREATE TABLE IF NOT EXISTS Hero (name TEXT PRIMARY KEY, gender TEXT, book TEXT);”; // 2.2 设置操作指令 _command.CommandText = sql; // 2.3 执行SQL操作 // 执行一个非查询的语句 _command.ExecuteNonQuery(); // 3. 添加数据 // 3.1 添加一行数据 string sql = @“INSERT INTO Hero VALUES (“萧炎”, “男”, “斗破苍穹”);”; _command.CommandText = sql; _command.ExecuteNonQuery(); // 3.2 添加多行数据,并返回这个语句对多少行数据产生影响 string[] names = { “林动”, “牧尘”, “叶凡”, “石昊”, “唐三”, “秦羽” }; string[] genders = {“男”, “男”, “男”, “男”, “女”, “女”}; string[] books = { “武动乾坤”, “大主宰”, “遮天”, “完美世界”, “斗罗大陆”, “星辰变” }; // SQL语句 string sql = “”; // 循环拼接 for (int i = 0; i < names.Length; i++) { sql += string.Format(“insert into Hero values (’{0}’, ‘{1}’, ‘{2}’);”, names[i], genders[i], books[i]); } _command.CommandText = sql; // 执行非查询语句并记录返回值 int result = _command.ExecuteNonQuery(); Debug.Log(result); // 4. 删除数据 _command.CommandText = @“delete from Hero where gender = ‘女’;”; int result = _command.ExecuteNonQuery(); Debug.Log(“删除了” + result + “行数据”); // 5. 修改数据 _command.CommandText = @“update Hero set gender = ‘不知道’ where name = ‘牧尘’;”; _command.ExecuteNonQuery(); // 6. 查询数据 // 6.1 返回查询到的数据中的第一行第一列 _command.CommandText = @“select * from Hero;”; object result = _command.ExecuteScalar(); Debug.Log(result); // 6.2 使用_reader来遍历获取所有的查询结果 _command.CommandText = @“select * from Hero;”; _reader = _command.ExecuteReader(); while (_reader.Read()) { string s = “”; // 6.2.1 通过键的名字来取 s += _reader[“name”] + " | "; s += _reader[“gender”] + " | "; s += _reader[“book”]; Debug.Log(s); // 6.2.2 通过键的下标来取 s += _reader[0] + " | "; s += _reader[1] + " | "; s += _reader[2]; Debug.Log(s); // 6.2.3 循环遍历 for (int i = 0; i < _reader.FieldCount; i++) { // 通过键下标, 获取键的名称 string key = _reader.GetName(i); // 通过键的下标, 获取键的值 object value = _reader.GetValue(i); s += _reader[i] + " | "; } Debug.Log(s); } // 注意!: _reader在使用结束后, 记得要关闭 _reader.Close(); // 7. 关闭数据库 private void OnDestroy() { _connection.Close(); }

Unity初级(十二)相关推荐

  1. Unity(十二):2D飞刀小游戏

    展示 http://www.4399.com/flash/221013.htm 项目源码地址(有详细注释) https://download.csdn.net/download/weixin_4352 ...

  2. Unity FairyGUI(十二)

    Unity FairyGUI(十二) 一.树 添加节点已经在树里了才能使用,也就是已经AddChild了. GTree目前不支持虚拟化 初始化结点最好通过(一下这种方式初始化) aTree.treeN ...

  3. 详解Unity中的粒子系统Particle System (十二 | 终)

    前言 终于来到了最后一篇,粒子系统宣告终结!这十来篇博客删删改改写了半个多月,真是离谱.今天该讲案例与粒子系统的应用,那么我们就进入正题吧! 目录 前言 本系列提要 一.如何做出效果 二.案例演示 1 ...

  4. Ruby‘s Adventrue游戏制作笔记(十二)Unity给角色添加简单的特效

    Ruby's Adventrue游戏制作笔记(十二)Unity给角色添加简单的特效 前言 一.把特效物品进行切割 二.创建 particle System 三.创建彩色球 四.再设置一下其他属性 五. ...

  5. Unity C# 网络学习(十二)——Protobuf生成协议

    Unity C# 网络学习(十二)--Protobuf生成协议 一.安装 去Protobuf官网下载对应操作系统的protoc,用于将.proto文件生成对应语言的协议语言文件 由于我使用的是C#所以 ...

  6. unity 罗盘 Android,Unity之一天一个技术点(十二)-罗盘的实现

    Unity之一天一个技术点(十二)---指南针的实现 指南针的实现(可据镜头旋转改变) 代码如下: 变量简述: compassGUISkin皮肤用来显示指南针贴图 标签Label贴图用来作为指南针背景 ...

  7. 流程图绘制初级:需要牢记的十二个描述规范

    我们常说,要画规范的流程图,很多学员就不解,流程图能把意思表示清楚,大家都明白什么意思就行了呗,干嘛还要"一板一眼"呢? 从项目角度来看,规范的流程图帮助项目组成员统一认识,便于项 ...

  8. 【单元复习】之标日初级下册第十一、十二单元

    第四十一课   (1)被动形式  意义 :表示做主语的人或事物承受某种动作或影响的表达方式.   动词变形 :  一类动词(五段动词):动词(ない形) + れる  二类动词(一段动词):去掉词尾 る ...

  9. “云时代架构”经典文章阅读感想十二

    云时代架构"经典文章阅读感想十二 (牛逼的架构师是怎么炼成的?) 前几周阅读的三四十岁的大龄程序员,应该如何保持自己的职场竞争力?中提到如何在35岁左右可以实现掌握有核心竞争力.其中之一便是 ...

  10. Android项目实战(二十二):启动另一个APP or 重启本APP

    Android项目实战(二十二):启动另一个APP or 重启本APP 原文:Android项目实战(二十二):启动另一个APP or 重启本APP 一.启动另一个APP 目前公司项目需求,一个主AP ...

最新文章

  1. 布尔定理及证明(完整版)
  2. 017_Spring+Mybatis+C3P0
  3. 关于数据访问模式(三)—— Data Accessor模式
  4. 线性表的实现及其基本操作
  5. Linux Shell脚本编程--grep命令
  6. java 判断是否为null_说说Java 对象不使用时为什么要赋值为 null?
  7. net MVC 重定向总结
  8. 5g时代计算机网络过时,5g云电脑 取代主机(5g时代云电脑会普及吗)
  9. R载入需要的程辑包:rJava Error
  10. Python开发规范
  11. Linux下SVN搭建与配置
  12. php仿大众点评,Android高仿大众点评(带服务端)
  13. jemalloc疑似内存泄漏分析
  14. cookie.setValue一些注意事项
  15. 使用它给 ​xxl-job 添加任务,太爽了
  16. 二分图匹配-匈牙利算法, 最小路径覆盖
  17. 分门别类总结Java中的各种锁,让你彻底记住
  18. oracle上机题库_Oracle笔试题库附参考答案
  19. 圆周率π是怎么算出来的,用程序怎么算
  20. Python 求一元二次方程的根(包括虚根)

热门文章

  1. css3制作广告栏效果的疑问? 1
  2. 苹果春季发布会看点汇总
  3. 猿创征文|磁盘满的本质分析——磁盘空间满与inode节点满
  4. 【11】FreeRTOS的延时函数
  5. 叶胜超:跨链双雄之Cosmos(宇宙)
  6. node用express写后端restful接口实战三:sequelize操作数据库:模型(Model)、迁移(Migration)与种子(Seeders)
  7. Springboot项目架构设计
  8. 比Siri更厉害的个人助理Viv 能否一统江湖?
  9. vue项目落地(qiankun.js)微前端服务
  10. 混沌工程-为什么推广的如此困难