补充:php
unity中sqlit不少sql命令用不了,貌似是阉割版,记录下使用过的java
1设置主键方法python
CREATE TABLE salespeople (
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT
);mysql
2主键只要是INTEGER,就是自增加linux
插入数据时能够不用插入主键,主键的位置用null代替,主键会自动自增加android
INSERT INTO table1 VALUES (null, 'aa', 'bb', 'cc' )
ios
http://blog.csdn.net/qinyuanpei/article/details/46812655
sql
各位朋友你们好,欢迎你们关注个人博客,我是秦元培,我是博客地址是http://blog.csdn.net/qinyuanpei。在经历了一段时间的忙碌后,博主终于有时间来研究新的东西啦,今天博客向和你们一块儿交流的内容是在Unity3D游戏开发中使用SQLite进行数据库开发,坦白来说,在个人技术体系中Web和数据库是相对薄弱的两个部分,所以正好这段时间项目须要和服务器、数据库进行交互,所以在接下来的文章中博主可能会更加倾向于讲解这方面的内容,但愿你们可以喜欢啊!mongodb
1、什么是SQLite?
SQLite是一款轻型的数据库,是遵照ACID的关系型数据库管理系统,它包含在一个相对小的C库中,以嵌入式做为它的设计目标,它占用资源很是的低,所以适合在嵌入式设备如Android、Ruby on Rails等中使用。它可以支持Windows/Linux/Unix等等主流的操做系统,同时可以跟和C、C++、Ruby、Python、C#、PHP、Java等编程语言相结合。SQLite是一个以文件形式存在的关系型数据库,尽管没法实现分布式和横向扩展,但是做为一个轻量级的嵌入式数据库,它不须要系统提供服务支持,经过SDK直接操做文件避免了对数据库维护的相关事务,从这个角度来说它是一个出色的数据库。数据库
2、为何要选择SQLite
好了,在了解了SQLite后,咱们来了解下SQLite有哪些让咱们心动的特性,或者说咱们为何要选择SQLite,由于在这个世界上咱们有太多的数据库能够选择,诸如Oracle、MySQL、SQLServer、DB二、NoSQL、MongoDB等等:
- ACID事务
- 零配置 – 无需安装和管理配置
- 储存在单一磁盘文件中的一个完整的数据库
- 数据库文件能够在不一样字节顺序的机器间自由的共享
- 支持数据库大小至2TB
- 足够小, 大体13万行C代码, 4.43M
- 比一些流行的数据库在大部分普通数据库操做要快—SQLite读写效率如此之高,会使用其余数据库的理由是?
- 简单, 轻松的API
- 包含TCL绑定, 同时经过Wrapper支持其余语言的绑定
- 良好注释的源代码, 而且有着90%以上的测试覆盖率
- 独立: 没有额外依赖
- 源码彻底的开源, 你能够用于任何用途, 包括出售它
- 支持多种开发语言,C, C++, PHP, Perl, Java, C#,Python, Ruby等
3、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。该类代码定义以下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
using UnityEngine;
using System.Collections;
using Mono.Data.Sqlite;
using System;
public class SQLiteHelper
{
private SqliteConnection dbConnection;
private SqliteCommand dbCommand;
private SqliteDataReader dataReader;
public SQLiteHelper(
string connectionString)
{
try{
dbConnection=
new SqliteConnection(connectionString);
dbConnection.Open();
}
catch(Exception e)
{
Debug.Log(e.Message);
}
}
public SqliteDataReader
ExecuteQuery(
string queryString)
{
dbCommand = dbConnection.CreateCommand();
dbCommand.CommandText = queryString;
dataReader = dbCommand.ExecuteReader();
return dataReader;
}
public void CloseConnection()
{
if(dbCommand !=
null){
dbCommand.Cancel();
}
dbCommand =
null;
if(dataReader !=
null){
dataReader.Close();
}
dataReader =
null;
if(dbConnection !=
null){
dbConnection.Close();
}
dbConnection =
null;
}
public SqliteDataReader
ReadFullTable(
string tableName)
{
string queryString =
"SELECT * FROM " + tableName;
return ExecuteQuery (queryString);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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#进行重写,我在此基础上进行了完善,再此对两位大神的无私付出表示感谢。这里要说明的有三点:
-
1、在Unity3D编辑器下生成数据库文件(.db)默认位于和Assets目录同级的位置,即项目的工程文件夹中。咱们能够经过修改路径在改变数据库文件的存储位置,具体来说:
Windows平台:data source=Application.dataPath/数据库名称.db
iOS平台:data source=Application.persistentDataPath/数据库名称.db
android平台:URL=file:Application.persistentDataPath/数据库名称.db(我想说Android平台就是个奇葩,搞什么特殊化嘛)
-
2、确保Unity3D编辑器中的.NET版本和MonoDevelop中的.NET版本都为2.0版本,在Unity3D中打包导出的程序可能不会保留数据库文件,所以须要手动将数据库文件拷贝到相应的位置,固然更加合理的方案是将数据库文件存放到StreamingAssets文件夹下,而后在第一次加载游戏的时候将数据库文件复制到对应平台上的存放位置。
-
3、在使用InsertValues方法时请参考SQLite中字段类型与C#中数据类型的对应关系,博主目前测试了int类型和string类型都没有什么问题,更多类型的数据请你们自行测试而后告诉博主测试的结果,若是你们有兴趣扩展这个辅助类的话能够自行去扩展哦,嘿嘿!
好了,千呼万唤始出来的时候到了,下面咱们以一个实例来完成今天的项目讲解,由于咱们已经定义好了SQLite的辅助类,所以咱们能够快速地编写出下面的脚本代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
using UnityEngine;
using System.Collections;
using System.IO;
using Mono.Data.Sqlite;
public class SQLiteDemo : MonoBehaviour
{
private SQLiteHelper sql;
void Start ()
{
sql =
new SQLiteHelper(
"data source=sqlite4unity.db");
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'"});
sql.UpdateValues(
"table1",
new string[]{
"Name"},
new string[]{
"'Zhang3'"},
"Name",
"=",
"'张三'");
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'"});
sql.DeleteValuesAND(
"table1",
new string[]{
"Name",
"Age"},
new string[]{
"=",
"="},
new string[]{
"'王五'",
"'26'"});
SqliteDataReader reader = sql.ReadFullTable (
"table1");
while(reader.Read())
{
Debug.Log(reader.GetInt32(reader.GetOrdinal(
"ID")));
Debug.Log(reader.GetString(reader.GetOrdinal(
"Name")));
Debug.Log(reader.GetInt32(reader.GetOrdinal(
"Age")));
Debug.Log(reader.GetString(reader.GetOrdinal(
"Email")));
}
reader = sql.ReadTable (
"table1",
new string[]{
"ID",
"Name"},
new string[]{
"Age"},
new string[]{
">="},
new string[]{
"'25'"});
while(reader.Read())
{
Debug.Log(reader.GetInt32(reader.GetOrdinal(
"ID")));
Debug.Log(reader.GetString(reader.GetOrdinal(
"Name")));
}
sql.ExecuteQuery(
"DELETE FROM table1 WHERE NAME='王五'");
sql.CloseConnection();
}
}
在上面的代码中咱们是在Start方法中建立了数据库和数据表,然而在实际使用中咱们须要判断数据库和数据表是否存在,所以若是你使用这段脚本提示错误信息,请确保数据库和数据表是否已经存在。好了,下面的截图展现了程序运行的结果:


做为一个强大的数据库怎么能没有图形化的数据库管理工具呢?因此这里博主向你们推荐一个免安装的小工具SqliteStudio,使用这个工具能够帮助咱们方便地管理Sqlite数据库里的数据,这样是否是比较方便呢?哈哈!这个工具能够从这里下载哦!

好了,今天的内容就是这样了,为了写这篇文章花了三个晚上准备,但愿你们喜欢啊!若是你们以为这篇文章有用,请继续关注个人博客,我是秦元培,个人博客地址是http://blog.csdn.net/qinyuanpei。
2015年11月3日更新内容:在不一样的平台上数据库的存储位置是不一样的,在这里给出一个参考的路径,但愿你们在处理移动端的时候注意这些问题啊!
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
//各平台下数据库存储的绝对路径(通用)
//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"路径便可