@[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. Too many levels of symbolic links
  3. java a标签正则_正则表达式:java中婚配HTML中a标签中的中文字符
  4. php memcached 扩展下载,编译安装 PHP 的 Memcached 扩展
  5. 从锤子手机谈产品的逼格
  6. 可网管交换机的三种管理方式介绍
  7. 主打“云安全” 迅雷系帝恩思登陆新三板
  8. [转帖]三大运营商2G/3G/4G频率分配和网络制式
  9. 关于WM_NOTIFY的使用方法
  10. error LNK2019: unresolved external symbol “__declspec(dllimport) public: __thiscall 的解决方案
  11. fping安装包linux,Linux安装fping和hping
  12. matlab2016a的光伏阵列,DAMPPT 光伏电池阵列输出功率受光照强度和温度变化的影响,因此最大 点跟踪( )技 matlab 272万源代码下载- www.pudn.com...
  13. asp.net调用前台js调用后台代码分享
  14. 腾讯教育 App Flutter 跨端点播组件实践
  15. python3 selenium xpath 下载斗鱼颜值主播头像 入门demo
  16. 鸿蒙能用谷歌地图,华为鸿蒙更进一步,牵手世界级应用,谷歌GMS或彻底再见
  17. 【报告分享】2021中国医生洞察报告-丁香园(附下载)
  18. 安装Python3.6.3+spyder
  19. 你知道有哪些正规的兼职平台吗?
  20. cisco rommon 维护路由器

热门文章

  1. 15K的前端应届毕业生,就因为掌握了这些知识点!(前端企业级开发必备)
  2. Android按返回键退出程序但不销毁,程序后台运行,同QQ退出处理方式
  3. 【华为机试真题 Python】一个正整数到 Excel 编号之间的转换
  4. 猿创征文|磁盘满的本质分析——磁盘空间满与inode节点满
  5. PHP小马免杀的浅谈[过最新D盾]
  6. python turtle画表情包
  7. vue3 render函数的写法
  8. Derby 和 Geronimo 使用感觉
  9. excel数据库_标签打印软件中Excel数据整理及导入
  10. H5前端性能测试点及优化方法