不管是什么数据库,SQL语句都是通用的,这里简单列举一下
Create Table 表名 (列1,类型,列2,类型,...)
Insert into 表名 values(列1,列2,...);
Delete from 表名 where 条件
Update 表名 set age=18 where 条件;
Select * from 表名
Select * from 表名 where 条件
查询本身是非常简单的,只需要输入相应的sql语句就行了,但是把查询的数据简单便捷的转化为对应的实体类是非常麻烦的,这里使用了“反射+泛型”得到需要查询的实体类,然后利用反射得到实体类的属性或者字段,然后赋值后直接返回需要的数据集合。
using System;
using System.Collections.Generic;
using UnityEngine;
using Mono.Data.Sqlite;
///
/// 数据库管理器
///
public class DBManager :MonoBehaviour{
private static DBManager _instance;
public static DBManager Instance
{
get
{
if (_instance == null)
{
GameObject go = new GameObject("DBManger");
_instance = go.AddComponent();
}
return _instance;
}
}
//用于建立数据库连接,保证数据流
SqliteConnection connection;
//数据库命令
SqliteCommand command;
//数据库阅读器
SqliteDataReader reader;
private const string dbName = "data";
void Awake()
{
InitDB();
OpenDB();
}
void OnDestroy()
{
CloseDB();
}
//拷贝数据库到沙盒目录
void InitDB()
{
Debug.Log("*-> DBManager->Init");
//判断是移动端
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
string systemDBPath = Application.persistentDataPath + "/data.db";
// copy data.db from steamingAssetsPath to persistentDataPath
if (!System.IO.File.Exists(systemDBPath))
{
CopyFileFromStreamingAssetsToPersistentDataPath("/data.db");
}
}
}
void CopyFileFromStreamingAssetsToPersistentDataPath(string relativePath)
{
string fileInStreamingAssets = Application.streamingAssetsPath + relativePath;
string fileInPersistentDataPath = Application.persistentDataPath + relativePath;
Debug.Log(fileInStreamingAssets + "->"+ fileInPersistentDataPath);
if (Application.platform == RuntimePlatform.Android)
{
WWW fileReader = new WWW(fileInStreamingAssets);
while (!fileReader.isDone) { }
//把www加载的数据库的bytes写入到沙盒的data.db
FileUtil.WriteFile(fileInPersistentDataPath, fileReader.bytes);
}
else
{
byte[] content = FileUtil.ReadFile(fileInStreamingAssets);
FileUtil.WriteFile(fileInPersistentDataPath, content);
}
}
public void OpenDB()
{
try
{
//指定数据库路径,一般放置到StreamingAsset下
string path = Application.streamingAssetsPath + "/" + dbName + ".db";
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
path = Application.persistentDataPath + "/" + dbName + ".db";
}
Debug.Log("dbPath:" + path);
//新建数据库连接
connection = new SqliteConnection(@"Data Source = " + path);
//打开数据库
connection.Open();
Debug.Log("打开数据库");
}
catch (Exception ex)
{
Debug.Log(ex.ToString());
}
}
public void CloseDB()
{
if(connection!=null)
connection.Close();
if (command != null)
command.Dispose();//Dispose用于释放,和Close功能一样
if (reader != null)
reader.Close();
Debug.Log("关闭数据库");
}
//创建表
//Activator.CreateInstance(type);//根据System.Type类型去实例化一个类
//var fields = type.GetFields();//根据System.Type类型拿到类中的字段
//fields[i].Name//得到单个字段的名字
//fields[i].Name//T t: type.GetField(fields[i].Name).GetValue(t);//得到T类型的t中field的值
//fields[i].Name//T t: type.GetField(fields[i].Name).SetValue(t,"新的值");//设置T类型的t中field的值
public void CreateTable()
{
var type = typeof(T);
string sql = "create Table "+type.Name+"(";
var fields = type.GetFields();
for (int i = 0; i < fields.Length; i++)
{
sql += "[" + fields[i].Name + "] " + CS2DB(fields[i].FieldType)+",";
}
sql = sql.TrimEnd(',') + ")";
Excute(sql);
}
public void Insert(T t)
{
var type = typeof(T);
string sql = "insert into " + type.Name + " values (";
var fields = type.GetFields();
foreach (var field in fields)
{
//通过反射得到对象中的值
sql += "'" + type.GetField(field.Name).GetValue(t) + "',";
}
sql = sql.TrimEnd(',') + ");";
Excute(sql);
}
//插入语句
//--insert into users values("小新",28,'男','371452646566256456',1235123123);
public void InsertInto(string tbName,params object[] objs)
{
string sql = "insert into " + tbName + " values (";
foreach (var item in objs)
{
sql += "'"+ item + "',";
}
//sql=sql.Substring(0, sql.Length - 1);
sql=sql.TrimEnd(',')+ ");";
Excute(sql);
}
//删除语句
public void DeleteAnd(string tbName,params object[] objs)
{
string sql = "delete from " + tbName + " where (";
for (int i = 0; i < objs.Length-1; i+=2)
{
sql += objs[i] + "='" + objs[i + 1] +"' and ";
}
sql=sql.Substring(0, sql.Length - 4)+ ");";
Excute(sql);
}
//修改语句
//--update users set age = 18 where name = '小史'and cardid isnull;
public void UpdateAnd(string tbName, object[] colums,params object[] conditions)
{
string sql = "update "+tbName+" set ";
for (int i = 0; i < colums.Length-1; i+=2)
{
sql += colums[i] + "='" + colums[i + 1] + "',";
}
sql = sql.TrimEnd(',') + " where (";
for (int i = 0; i < conditions.Length-1; i+=2)
{
sql += conditions[i] + "='" + conditions[i + 1]+"' and ";
}
sql = sql.Substring(0, sql.Length - 4) + ");";
Excute(sql);
}
//查询>字典
public Liststring, string>> Select(string tbName)
{
string sql = "select * from " + tbName;
Excute(sql);
Liststring, string>> result = new Liststring, string>>();
while(reader.Read())
{
var dic = new Dictionary<string, string>();
for (int i = 0; i < reader.FieldCount; i++)
{
dic.Add(reader.GetName(i), reader.GetValue(i).ToString());
}
result.Add(dic);
}
return result;
}
///
/// 泛型约束
/// class :引用类型
/// struct:值类型
/// 接口和抽象类
/// 普通类
/// new():无参构造,(必须是最后一个约束)
///
//查询:泛型实体类(复用性高,灵活)
public List Select() where T: new()
{
var type = typeof(T);
string sql = "select * from " + type.Name;
Excute(sql);
List result = new List();
var fields = type.GetFields();
while (reader.Read())//读取下一行数据
{
T t = new T();//使用new() 实例化T
for (int i = 0; i < reader.FieldCount; i++)
{
string key = reader.GetName(i);//获取数据库指定列的key
object value = reader.GetValue(i);//获取数据库指定列的值
Debug.Log(key + ":" + value);
type.GetField(key).SetValue(t, value);//使用反射给T类型t赋值
}
result.Add(t);
}
return result;
}
///
/// 通过Id查询数据
///
public T SelectById(string id) where T:new()
{
Type type = typeof(T);
string sql = "select * from " + type.Name + " where id='" + id+"'";
Excute(sql);
T t = new T();
reader.Read();
var count = reader.FieldCount;
for (int i = 0; i < count; i++)
{
string key = reader.GetName(i);
object value = reader.GetValue(i);
type.GetField(key).SetValue(t, value);
}
return t;
}
void Excute(string sql)
{
Debug.LogWarning(sql);
//创建数据库连接命令
command = connection.CreateCommand();
//设置命令语句
command.CommandText = sql;
//执行命令
reader = command.ExecuteReader();
}
string CS2DB(Type type)
{
string result = "Text";
if(type==typeof(Int32))
{
result = "Int";
}
else if (type == typeof(String))
{
result = "Text";
}
else if (type == typeof(Single))
{
result = "FLOAT";
}
else if (type == typeof(Boolean))
{
result = "Bool";
}
return result;
}
}