惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V2EX - 技术
V2EX - 技术
P
Privacy International News Feed
Security Latest
Security Latest
H
Hacker News: Front Page
T
Tenable Blog
The Hacker News
The Hacker News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Security @ Cisco Blogs
Project Zero
Project Zero
O
OpenAI News
AI
AI
Spread Privacy
Spread Privacy
C
CERT Recently Published Vulnerability Notes
The Last Watchdog
The Last Watchdog
G
GRAHAM CLULEY
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Scott Helme
Scott Helme
Application and Cybersecurity Blog
Application and Cybersecurity Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
NISL@THU
NISL@THU
A
Arctic Wolf
T
Threat Research - Cisco Blogs
PCI Perspectives
PCI Perspectives
N
News and Events Feed by Topic
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cybersecurity and Infrastructure Security Agency CISA
Simon Willison's Weblog
Simon Willison's Weblog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Know Your Adversary
Know Your Adversary
Google Online Security Blog
Google Online Security Blog
罗磊的独立博客
L
LINUX DO - 最新话题
U
Unit 42
S
Security Affairs
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
博客园 - 【当耐特】
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
月光博客
月光博客
Engineering at Meta
Engineering at Meta
腾讯CDC
F
Full Disclosure
Cyberwarzone
Cyberwarzone
S
SegmentFault 最新的问题
Recorded Future
Recorded Future
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
The Cloudflare Blog

元视角

.NET 生态下的 Agent 框架选型:从 ReAct 到原生推理 - 元视角 从「能用」到「好用」:LLM 流式响应实现方式的探索之路 - 元视角 当我用 2000 条聊天记录,让 AI 为我画一幅自画像 - 元视角 基于 Supabase 的 AI 应用开发探索 - 元视角 微博 × MCP:社交媒体新玩法解锁 - 元视角 四点钟海棠花未眠 - 元视角 Semantic Kernel × MCP:智能体的上下文增强探索 - 元视角 基于 K-Means 聚类分析实现人脸照片的快速分类 - 元视角 容器技术驱动下的代码沙箱实践与思考 - 元视角 温故而知新:后端通用查询方案的再思考 - 元视角 浅议 CancellationToken 在前后端协同取消场景中的应用 - 元视角 Semantic Kernel 视角下的 Text2SQL 实践与思考 - 元视角 关于 ChatGPT 的流式传输,你需要知道的一切 - 元视角 RAG 的是与非、Rewrite 和 Rerank - 元视角 使用 EFCore 和 PostgreSQL 实现向量存储及检索 - 元视角 基于 LLaMA 和 LangChain 实践本地 AI 知识库 - 元视角 使用 llama.cpp 在本地部署 AI 大模型的一次尝试 - 元视角 如何为 Git 配置多个 SSH Key - 元视角 C# 使用 LibUsbDotNet 实现 USB 设备检测 - 元视角 基于 C# 实现样式与数据分离的打印方案 - 元视角 基于 SVG 的图形交互方案实践 - 元视角 前端视频播放技术概览 - 元视角 温故而知新,再话 Python 动态导入 - 元视角 后 GPT 时代,NLP 不存在了? - 元视角 视频是不能 P 的系列:使用 Milvus 实现海量人脸快速检索 - 元视角 GDI+下字体大小自适应方案初探 - 元视角 小爱音箱集成 ChatGPT 的不完全教程 - 元视角 程序员视角下的三体世界随想 - 元视角 关于 Docker 容器配置信息的渐进式思考 - 元视角 在 Docker 容器内集成 Crontab 定时任务 - 元视角 为你的服务器集成 LDAP 认证 - 元视角 似花还似非花 - 元视角 视频是不能 P 的系列:使用 Dlib 实现人脸识别 - 元视角 浅议分布式链路追踪与日志的整合 - 元视角 关于 Git 大文件上传这件小事 - 元视角 .NET 进程内队列 Channel 的入门与应用 - 元视角 使用 Fody 实现 .NET 的静态编织 - 元视角 .NET Core + ELK 搭建可视化日志分析平台(下) - 元视角 聊一聊前端图片懒加载背后的故事 - 元视角 支持外部链接跳转的 Vue Router 扩展实现 - 元视角 视频是不能 P 的系列:OpenCV 和 Dlib 实现表情包 - 元视角 不得不说的 ASP.NET Core 集成测试 - 元视角 再议 DDD 视角下的 EFCore 与 领域事件 - 元视角 Vue.js 前端项目容器化部署实践极简教程 - 元视角 再见,人间四月天 - 元视角 Python 图像风格化迁移助力画家梦想 - 元视角 利用 ASP.NET Core 中的标头传播实现分布式链路追踪 - 元视角 利用 gRPC 实现文件的上传与下载 - 元视角 七种武器:延迟队列的原理和实现总结 - 元视角 gRPC 流式传输极简入门指南 - 元视角 Envoy 集成 Jaeger 实现分布式链路追踪 - 元视角 浅议非典型 Web 应用场景下的身份认证 - 元视角 gRPC 借助 Any 类型实现接口的泛化调用 - 元视角 分布式丛林探险系列之 Redis 集群模式 - 元视角 分布式丛林探险系列之 Redis 主从复制模式 - 元视角 通过 Python 预测 2021 年双十一交易额 - 元视角 gRPC 搭配 Swagger 实现微服务文档化 - 元视角 SSL/TLS 加密传输与数字证书的前世今生 - 元视角 使用 Python 自动识别防疫健康码 - 元视角 你不可不知的容器编排进阶技巧 - 元视角 ASP.NET Core 搭载 Envoy 实现 gRPC 服务代理 - 元视角 再话 AOP,从简化缓存操作说起 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务身份认证(JWT) - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的监控预警 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的反向代理 - 元视角 ASP.NET Core gRPC 打通前端世界的尝试 - 元视角 EFCore 实体命名约定库:EFCore.NamingConventions - 元视角 ASP.NET Core gRPC 集成 Polly 实现优雅重试 - 元视角 ASP.NET Core gRPC 健康检查的探索与实现 - 元视角 ASP.NET Core gRPC 拦截器的使用技巧分享 - 元视角 SnowNLP 使用自定义语料进行模型训练 - 元视角 使用 HttpMessageHandler 实现 HttpClient 请求管道自定义 - 元视角 ABP vNext 的实体与服务扩展技巧分享 - 元视角 ABP vNext 对接 Ant Design Vue 实现分页查询 - 元视角 源代码探案系列之 .NET Core 跨域中间件 CORS - 元视角 源代码探案系列之 .NET Core 限流中间件 AspNetCoreRateLimit - 元视角 源代码探案系列之 .NET Core 并发限制中间件 ConcurrencyLimiter - 元视角 通过 EmbededFileProvider 实现 Blazor 的静态文件访问 - 元视角 低代码,想说爱你不容易 - 元视角 记一次失败的 ThoughtWorks 面试经历 - 元视角 从 C# 1.0 到 C# 9.0,历代 C# 语言特性一览 - 元视角 通过 Python 分析 2020 年全年微博热搜数据 - 元视角 基于 Python 和 Selenium 实现 CSDN 一键三连自动化 - 元视角 使用多线程为你的 Python 爬虫提速的 N 种姿势,你会几种? - 元视角 实现网页长截图的常见思路总结 - 元视角 温故而知新,由 ADO.NET 与 Dapper 所联想到的 - 元视角 视频是不能 P 的系列:OpenCV 人脸检测 - 元视角 作为技术宅的我,是这样追鬼滅の刃的 - 元视角 使用 Python 抽取《半泽直树》原著小说人物关系 - 元视角 厉害了!打工人用 Python 分析西安市职位信息 - 元视角 使用 dotTrace 对 .NET 应用进行性能分析与优化 - 元视角 一道 HashSet 面试题引发的蝴蝶效应 - 元视角 基于选项模式实现.NET Core 的配置热更新 - 元视角 Dapper.Contrib 在 Oracle 环境下引发 ORA-00928 异常问题的解决 - 元视角 .NET Core 中对象池(Object Pool)的使用 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(下):EventBus 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(中):RabbitMQ 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(上):基础篇 - 元视角 记一次从已损坏的 Git 仓库中找回代码的经历 - 元视角 .NET Core 原生 DI 扩展之属性注入实现 - 元视角
Unity3D 游戏开发之 SQLite 让数据库开发更简单 - 元视角
飞鸿踏雪 · 2015-07-09 · via 元视角

各位朋友大家好,欢迎大家关注我的博客,我是秦元培,我是博客地址是http://blog.csdn.net/qinyuanpei。在经历了一段时间的忙碌后,博主终于有时间来研究新的东西啦,今天博客向和大家一起交流的内容是在 Unity3D 游戏开发中使用 SQLite 进行数据库开发,坦白来讲,在我的技术体系中 Web 和数据库是相对薄弱的两个部分,因此正好这段时间项目需要和服务器、数据库进行交互,因此在接下来的文章中博主可能会更加倾向于讲解这方面的内容,希望大家能够喜欢啊!

什么是 SQLite?

SQLite是一款轻型的数据库,是遵守 ACID 的关系型数据库管理系统,它包含在一个相对小的 C 库中,以嵌入式作为它的设计目标,它占用资源非常的低,因此适合在嵌入式设备如 Android、Ruby on Rails 等中使用。它能够支持 Windows/Linux/Unix 等等主流的操作系统,同时能够跟和 C、C++、Ruby、Python、C#、PHP、Java 等编程语言相结合。SQLite 是一个以文件形式存在的关系型数据库,尽管无法实现分布式和横向扩展,可是作为一个轻量级的嵌入式数据库,它不需要系统提供服务支持,通过 SDK 直接操作文件避免了对数据库维护的相关事务,从这个角度来讲它是一个出色的数据库。

为什么要选择 SQLite

好了,在了解了 SQLite 后,我们来了解下 SQLite 有哪些让我们心动的特性,或者说我们为什么要选择 SQLite,因为在这个世界上我们有太多的数据库可以选择,诸如 Oracle、MySQL、SQLServer、DB2、NoSQL、MongoDB 等等:

  • ACID 事务
  • 零配置 – 无需安装和管理配置
  • 储存在单一磁盘文件中的一个完整的数据库
  • 数据库文件可以在不同字节顺序的机器间自由的共享
  • 支持数据库大小至 2TB
  • 足够小, 大致 13 万行 C 代码, 4.43M
  • 比一些流行的数据库在大部分普通数据库操作要快—SQLite 读写效率如此之高,会使用其他数据库的理由是?
  • 简单, 轻松的 API
  • 包含 TCL 绑定, 同时通过 Wrapper 支持其他语言的绑定
  • 良好注释的源代码, 并且有着90%以上的测试覆盖率
  • 独立: 没有额外依赖
  • 源码完全的开源, 你可以用于任何用途, 包括出售它
  • 支持多种开发语言,C, C++, PHP, Perl, Java, C#,Python, Ruby 等

Unity3D 中的 SQLite

在 Unity3D 中使用 SQLite,我们首先要明白这样一件事情,即我们这里的使用的 SQLite 并非是通常意义上的 SQLite.NET,而是经过移植后的 Mono.Data.Sqlite。因为 Unity3D 基于 Mono,因此使用移植后的 Mono.Data.Sqlite 能够减少我们的项目在不同平台上出现各种各样的问题。在 Unity3D 中使用的 SQLite 以 Mono.Data.Sqlite.dll 即动态链接库的形式给出,因此我们需要将这个文件放置在项目目录下的 Plugins 文件夹中,此外我们需要 System.Data.dll 或者 Mono.Data.dll 这两个文件添加到 Plugins 目录中,因为我们需要的部分数据相关的 API 或者类都定义在这两个文件当中,这些文件可以从这里直接下载。

PS:博主注意到在网上有使用 Mono.Data.SQLiteClient.dll 这个库实现在 Unity3D 操作 SQLite 数据库的相关文章,博主大概看了下,感觉和使用 Mono.Data.Sqlite.dll 这个库大同小异,大家喜欢哪个就用哪个吧!哈哈!博主在开源社区找到一个版本库,据说可以同时支持.NET 和 Mono,如果大家感兴趣欢迎大家去测试啊,哈哈!

在正式开始写代码前,我们首先来回顾下通常情况下数据库读写的基本流程吧!

  • 定义数据库连接字符串(ConnectionString)完成数据库连接的构造,建立或者打开一个数据库。
  • 定义相关的 SQL 命令(Command)通过这些命令实现对数据库的增加、删除、更新、读取四种基本功能。
  • 在完成各种数据库操作后及时关闭数据库连接,解除对数据库的连接和引用。

SQLite 作为一款优秀的数据库,在为其编写数据库相关代码时同样遵循这样的流程,考虑到对数据库的增加、删除、更新、读取四种操作具有类似性和统一性,因此在动手写 Unity3D 脚本前,首先让我们来编写一个 SQLite 的辅助类 SQLiteHelper.cs。该类代码定义如下:

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

public class SQLiteHelper
{
	/// <summary>
	/// 数据库连接定义
	/// </summary>
	private SqliteConnection dbConnection;

	/// <summary>
	/// SQL命令定义
	/// </summary>
	private SqliteCommand dbCommand;

	/// <summary>
	/// 数据读取定义
	/// </summary>
	private SqliteDataReader dataReader;

	/// <summary>
	/// 构造函数	
	/// </summary>
	/// <param name="connectionString">数据库连接字符串</param>
	public SQLiteHelper(string connectionString)
	{
		try{
			//构造数据库连接
			dbConnection=new SqliteConnection(connectionString);
			//打开数据库
			dbConnection.Open();
		}catch(Exception e)
		{
			Debug.Log(e.Message);
		}
	}

	/// <summary>
	/// 执行SQL命令
	/// </summary>
	/// <returns>The query.</returns>
	/// <param name="queryString">SQL命令字符串</param>
	public SqliteDataReader ExecuteQuery(string queryString)
	{
		dbCommand = dbConnection.CreateCommand();
		dbCommand.CommandText = queryString;
		dataReader = dbCommand.ExecuteReader();
		return dataReader;
	}

	/// <summary>
	/// 关闭数据库连接
	/// </summary>
	public void CloseConnection()
	{
		//销毁Command
		if(dbCommand != null){
			dbCommand.Cancel();
		}
		dbCommand = null;

		//销毁Reader
		if(dataReader != null){
			dataReader.Close();
		}
		dataReader = null;

		//销毁Connection
		if(dbConnection != null){
			dbConnection.Close();
		}
		dbConnection = null;
	}

	/// <summary>
	/// 读取整张数据表
	/// </summary>
	/// <returns>The full table.</returns>
	/// <param name="tableName">数据表名称</param>
	public SqliteDataReader ReadFullTable(string tableName)
	{
		string queryString = "SELECT * FROM " + tableName;
		return ExecuteQuery (queryString);
	}

	/// <summary>
	/// 向指定数据表中插入数据
	/// </summary>
	/// <returns>The values.</returns>
	/// <param name="tableName">数据表名称</param>
	/// <param name="values">插入的数值</param>
	public SqliteDataReader InsertValues(string tableName,string[] values)
	{
		//获取数据表中字段数目
		int fieldCount=ReadFullTable(tableName).FieldCount;
		//当插入的数据长度不等于字段数目时引发异常
		if(values.Length!=fieldCount){
			throw new SqliteException("values.Length!=fieldCount");
		}

		string queryString = "INSERT INTO " + tableName + " VALUES (" + values[0];
		for(int i=1; i<values.Length; i++)
		{
			queryString+=", " + values[i];
		}
		queryString += " )";
		return ExecuteQuery(queryString);
	}

	/// <summary>
	/// 更新指定数据表内的数据
	/// </summary>
	/// <returns>The values.</returns>
	/// <param name="tableName">数据表名称</param>
	/// <param name="colNames">字段名</param>
	/// <param name="colValues">字段名对应的数据</param>
	/// <param name="key">关键字</param>
	/// <param name="value">关键字对应的值</param>
	public SqliteDataReader UpdateValues(string tableName,string[] colNames,string[] colValues,string key,string operation,string value)
	{
		//当字段名称和字段数值不对应时引发异常
		if(colNames.Length!=colValues.Length) {
			throw new SqliteException("colNames.Length!=colValues.Length");
		}

		string queryString = "UPDATE " + tableName + " SET " + colNames[0] + "=" + colValues[0];
		for(int i=1; i<colValues.Length; i++) 
		{
			queryString+=", " + colNames[i] + "=" + colValues[i];
		}
		queryString += " WHERE " + key + operation + value;
		return ExecuteQuery(queryString);
	}

	/// <summary>
	/// 删除指定数据表内的数据
	/// </summary>
	/// <returns>The values.</returns>
	/// <param name="tableName">数据表名称</param>
	/// <param name="colNames">字段名</param>
	/// <param name="colValues">字段名对应的数据</param>
	public SqliteDataReader DeleteValuesOR(string tableName,string[] colNames,string[] operations,string[] colValues)
	{
		//当字段名称和字段数值不对应时引发异常
		if(colNames.Length!=colValues.Length || operations.Length!=colNames.Length || operations.Length!=colValues.Length) {
			throw new SqliteException("colNames.Length!=colValues.Length || operations.Length!=colNames.Length || operations.Length!=colValues.Length");
		}

		string queryString = "DELETE FROM " + tableName + " WHERE " + colNames[0] + operations[0] + colValues[0];
		for(int i=1; i<colValues.Length; i++) 
		{
			queryString+="OR " + colNames[i] + operations[0] + colValues[i];
		}
		return ExecuteQuery(queryString);
	}

	/// <summary>
	/// 删除指定数据表内的数据
	/// </summary>
	/// <returns>The values.</returns>
	/// <param name="tableName">数据表名称</param>
	/// <param name="colNames">字段名</param>
	/// <param name="colValues">字段名对应的数据</param>
	public SqliteDataReader DeleteValuesAND(string tableName,string[] colNames,string[] operations,string[] colValues)
	{
		//当字段名称和字段数值不对应时引发异常
		if(colNames.Length!=colValues.Length || operations.Length!=colNames.Length || operations.Length!=colValues.Length) {
			throw new SqliteException("colNames.Length!=colValues.Length || operations.Length!=colNames.Length || operations.Length!=colValues.Length");
		}

		string queryString = "DELETE FROM " + tableName + " WHERE " + colNames[0] + operations[0] + colValues[0];
		for(int i=1; i<colValues.Length; i++) 
		{
			queryString+=" AND " + colNames[i] + operations[i] + colValues[i];
		}
		return ExecuteQuery(queryString);
	}

	/// <summary>
	/// 创建数据表
	/// </summary> +
	/// <returns>The table.</returns>
	/// <param name="tableName">数据表名</param>
	/// <param name="colNames">字段名</param>
	/// <param name="colTypes">字段名类型</param>
	public SqliteDataReader CreateTable(string tableName,string[] colNames,string[] colTypes)
	{
		string queryString = "CREATE TABLE " + tableName + "( " + colNames [0] + " " + colTypes [0];
		for (int i=1; i<colNames.Length; i++) 
		{
			queryString+=", " + colNames[i] + " " + colTypes[i];
		}
		queryString+= "  ) ";
		return ExecuteQuery(queryString);
	}

	/// <summary>
	/// Reads the table.
	/// </summary>
	/// <returns>The table.</returns>
	/// <param name="tableName">Table name.</param>
	/// <param name="items">Items.</param>
	/// <param name="colNames">Col names.</param>
	/// <param name="operations">Operations.</param>
	/// <param name="colValues">Col values.</param>
	public SqliteDataReader ReadTable(string tableName,string[] items,string[] colNames,string[] operations, string[] colValues)
	{
		string queryString = "SELECT " + items [0];
		for (int i=1; i<items.Length; i++) 
		{
			queryString+=", " + items[i];
		}
		queryString += " FROM " + tableName + " WHERE " + colNames[0] + " " +  operations[0] + " " + colValues[0];
		for (int i=0; i<colNames.Length; i++) 
		{
			queryString+=" AND " + colNames[i] + " " + operations[i] + " " + colValues[0] + " ";
		}
		return ExecuteQuery(queryString);
	}
}

SQLiteHelper 类主要实现了数据库、数据表的创建以及数据表中记录的增加、删除、更新、读取四种基本功能。该类最初由国外的 Unity3D 开发者发布在Unity3D 官方论坛,后来经宣雨松使用C#进行重写,我在此基础上进行了完善,再此对两位大神的无私付出表示感谢。这里要说明的有三点:

  • 一、在 Unity3D 编辑器下生成数据库文件(.db)默认位于和 Assets 目录同级的位置,即项目的工程文件夹中。我们可以通过修改路径在改变数据库文件的存储位置,具体来讲: Windows 平台:data source=Application.dataPath/数据库名称.db IOS 平台:data source=Application.persistentDataPath/数据库名称.db Android 平台:URL=file:Application.persistentDataPath/数据库名称.db(我想说 Android 平台就是个奇葩,搞什么特殊化嘛)

  • 二、确保 Unity3D 编辑器中的.NET 版本和 MonoDevelop 中的.NET 版本都为 2.0 版本,在 Unity3D 中打包导出的程序可能不会保留数据库文件,因此需要手动将数据库文件拷贝到相应的位置,当然更加合理的方案是将数据库文件存放到 StreamingAssets 文件夹下,然后在第一次加载游戏的时候将数据库文件复制到对应平台上的存放位置。

  • 三、在使用 InsertValues 方法时请参考 SQLite 中字段类型与 C#中数据类型的对应关系,博主目前测试了 int 类型和 string 类型都没有什么问题,更多类型的数据请大家自行测试然后告诉博主测试的结果,如果大家有兴趣扩展这个辅助类的话可以自行去扩展哦,嘿嘿!

好了,千呼万唤始出来的时候到了,下面我们以一个实例来完成今天的项目讲解,因为我们已经定义好了 SQLite 的辅助类,因此我们可以快速地编写出下面的脚本代码:

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

public class SQLiteDemo : MonoBehaviour 
{
	/// <summary>
	/// SQLite数据库辅助类
	/// </summary>
	private SQLiteHelper sql;

	void Start () 
	{
		//创建名为sqlite4unity的数据库
		sql = new SQLiteHelper("data source=sqlite4unity.db");

		//创建名为table1的数据表
		sql.CreateTable("table1",new string[]{"ID","Name","Age","Email"},new string[]{"INTEGER","TEXT","INTEGER","TEXT"});

		//插入两条数据
		sql.InsertValues("table1",new string[]{"'1'","'张三'","'22'","'Zhang3@163.com'"});
		sql.InsertValues("table1",new string[]{"'2'","'李四'","'25'","'Li4@163.com'"});

		//更新数据,将Name="张三"的记录中的Name改为"Zhang3"
		sql.UpdateValues("table1", new string[]{"Name"}, new string[]{"'Zhang3'"}, "Name", "=", "'张三'");

		//插入3条数据
		sql.InsertValues("table1",new string[]{"3","'王五'","25","'Wang5@163.com'"});
		sql.InsertValues("table1",new string[]{"4","'王五'","26","'Wang5@163.com'"});
		sql.InsertValues("table1",new string[]{"5","'王五'","27","'Wang5@163.com'"});

		//删除Name="王五"且Age=26的记录,DeleteValuesOR方法类似
		sql.DeleteValuesAND("table1", new string[]{"Name","Age"}, new string[]{"=","="}, new string[]{"'王五'","'26'"});

		//读取整张表
		SqliteDataReader reader = sql.ReadFullTable ("table1");
		while(reader.Read()) 
		{
			//读取ID
			Debug.Log(reader.GetInt32(reader.GetOrdinal("ID")));
			//读取Name
			Debug.Log(reader.GetString(reader.GetOrdinal("Name")));
			//读取Age
			Debug.Log(reader.GetInt32(reader.GetOrdinal("Age")));
			//读取Email
			Debug.Log(reader.GetString(reader.GetOrdinal("Email")));
		}

		//读取数据表中Age>=25的所有记录的ID和Name
		reader = sql.ReadTable ("table1", new string[]{"ID","Name"}, new string[]{"Age"}, new string[]{">="}, new string[]{"'25'"});
		while(reader.Read()) 
		{
			//读取ID
			Debug.Log(reader.GetInt32(reader.GetOrdinal("ID")));
			//读取Name
			Debug.Log(reader.GetString(reader.GetOrdinal("Name")));
		}

		//自定义SQL,删除数据表中所有Name="王五"的记录
		sql.ExecuteQuery("DELETE FROM table1 WHERE NAME='王五'");

		//关闭数据库连接
		sql.CloseConnection();
	}
}

在上面的代码中我们是在 Start 方法中创建了数据库和数据表,然而在实际使用中我们需要判断数据库和数据表是否存在,因此如果你使用这段脚本提示错误信息,请确保数据库和数据表是否已经存在。好了,下面的截图展示了程序运行的结果:

数据库效果演示 数据库效果演示

Unity3D效果展示 Unity3D效果展示

作为一个强大的数据库怎么能没有图形化的数据库管理工具呢?所以这里博主向大家推荐一个免安装的小工具 SqliteStudio,使用这个工具可以帮助我们方便地管理 Sqlite 数据库里的数据,这样是不是比较方便呢?哈哈!这个工具可以从这里下载哦!

SQLiteStudio界面演示 SQLiteStudio界面演示

好了,今天的内容就是这样了,为了写这篇文章花了三个晚上准备,希望大家喜欢啊!如果大家觉得这篇文章有用,请继续关注我的博客,我是秦元培,我的博客地址是http://blog.csdn.net/qinyuanpei

2015 年 11 月 3 日更新内容如下:不同平台上的数据库存储路径

        //各平台下数据库存储的绝对路径(通用)
        //PC:sql = new SQLiteHelper("data source=" + Application.dataPath + "/sqlite4unity.db");
        //Mac:sql = new SQLiteHelper("data source=" + Application.dataPath + "/sqlite4unity.db");
        //Android:sql = new SQLiteHelper("URI=file:" + Application.persistentDataPath + "/sqlite4unity.db");
        //iOS:sql = new SQLiteHelper("data source=" + Application.persistentDataPath + "/sqlite4unity.db");

        //PC平台下的相对路径
        //sql = new SQLiteHelper("data source="sqlite4unity.db");
        //编辑器:Assets/sqlite4unity.db
        //编译后:和AppName.exe同级的目录下,这里比较奇葩
        //当然可以用更随意的方式sql = new SQLiteHelper("data source="D://SQLite//sqlite4unity.db");
        //确保路径存在即可否则会发生错误

        //如果是事先创建了一份数据库
        //可以将这个数据库放置在StreamingAssets目录下然后再拷贝到
        //Application.persistentDataPath + "/sqlite4unity.db"路径即可