在Unity中使用sqlite的教程有很多。
看完这两篇呢,基本上对sqlite数据库的使用都没有问题了,但是想在Unity中更方便的使用,我有对两者进行了改进和升级。
1.SqliteManager类
核心功能,使用C#函数,代替复杂的sql语句
using UnityEngine;
using System.Collections.Generic;
using Mono.Data.Sqlite;
public class SqlManager : MonoSingleton{
private const string dbName = "DBNAME";
//链接数据库
private SqliteConnection connection;
//数据库命令
private SqliteCommand command;
//数据库阅读器
private SqliteDataReader reader;
//打开数据库
public void OpenDB(string dbName)
{
try
{ //链接数据库操作
string dbPath = Application.streamingAssetsPath + "/" + dbName + ".db";
//固定sqlite格式data source
connection = new SqliteConnection(@"Data Source = " + dbPath);
connection.Open();
Debug.Log("DataBase Connect");
}
catch (System.Exception e)
{
Debug.LogError(e.ToString());
}
}
//关闭数据库
public void CloseDB()
{
/*
* IDispose接口可以通过Using(){}关键字实现使用后立刻销毁
* Close ()方法回滚任何挂起的事务。然后,它将连接释放到连接池,或者在连接池被禁用的情况下关闭连接,
* 应用程序可以多次调用 Close。不会生成任何异常。
* Dispose()方法实际是和close()做的同一件事,唯一的区别是Dispose方法清空了connectionString,即设置为了null.
*/
if (reader != null)
reader.Close();
if (command != null)
command.Dispose();
if (connection != null)
connection.Close();
Debug.Log("DataBase Close");
}
//创建数据库表
public void CreateTabel(string _tableName,string[] col,string[] colType)
{
//string createSql = "CREATE TABLE player(ID int,name text,damage int)";
if (col.Length != colType.Length)
{
Debug.LogError("Colum's Length != ColumType's Length");
return;
}
string sql = "CREATE TABLE "+_tableName+"(";
for(int i=0;i<col.Length;i++)
{
sql += col[i] + " " + colType[i] + ",";
}
sql = sql.TrimEnd(',');
sql += ")";
ExcuteSql(sql);
}
//插入数据
public void Insert(string _tableName,object[] values)
{
//string createSql = "INSERT INTO player(ID,name,damage) VALUES (102,'ak47',120)";
if (values.Length == 0)
Debug.LogError("Values's length == 0");
string sql = "INSERT INTO "+_tableName + " VALUES(";
foreach(object value in values)
{
sql += "'" + value.ToString() + "'" +",";
}
sql = sql.TrimEnd(',');
sql += ")";
ExcuteSql(sql);
}
//删除数据 OR
public void DeleteOR(string _tabelName, params object[] colums)
{
//string createSql = "delete from player where rowid=1";
if (colums == null || colums.Length == 0)
Debug.LogError("colums == null || colums.Length == 0");
string sql = "DELETE FROM " + _tabelName + " WHERE ";
for (int i = 0; i < colums.Length; i += 2)
{
sql += colums[i] + " = '" + colums[i + 1].ToString() + "' OR ";
}
sql = sql.Remove(sql.Length - 3);
ExcuteSql(sql);
}
//删除数据 AND
public void DeleteAND(string _tabelName, params object[] colums)
{
if (colums == null || colums.Length == 0)
Debug.LogError("colums == null || colums.Length == 0");
string sql = "DELETE FROM " + _tabelName + " WHERE ";
for (int i=0;i<colums.Length;i+=2)
{
sql += colums[i] + " = '" + colums[i+1].ToString() + "' AND ";
}
sql = sql.Remove(sql.Length - 4);
ExcuteSql(sql);
}
//更新数据 OR
public void UpdateOR(string _tableNmae,object[] colums, params object[] options)
{
//string createSql = "Update player set name='M16' where id=102";
if (colums == null || colums.Length == 0 || colums.Length % 2 == 1)
Debug.LogError("colums Length has error!!!");
if (options == null || options.Length == 0 || options.Length % 2 == 1)
Debug.LogError("options Length has error!!!");
string sql = "UPDATE " + _tableNmae + " SET ";
for (int i = 0; i < colums.Length; i += 2)
{
sql += colums[i] + " = '" + colums[i + 1].ToString() + "' ";
}
sql += " WHERE ";
for (int i = 0; i < options.Length; i+=2)
{
sql += options[i] + "=" + options[i+1].ToString() + " OR ";
}
sql = sql.Remove(sql.Length - 3);
ExcuteSql(sql);
}
//更新数据 AND
public void UpdateAND(string _tableNmae, object[] colums, params object[] options)
{
//string createSql = "Update player set name='M16' where id=102";
if (colums == null || colums.Length == 0 || colums.Length % 2 == 1)
Debug.LogError("colums Length has error!!!");
if (options == null || options.Length == 0 || options.Length % 2 == 1)
Debug.LogError("options Length has error!!!");
string sql = "UPDATE " + _tableNmae + " SET ";
for (int i = 0; i < colums.Length; i += 2)
{
sql += colums[i] + " = '" + colums[i + 1].ToString() + "' ";
}
sql += " WHERE ";
for (int i = 0; i < options.Length; i += 2)
{
sql += options[i] + "=" + options[i + 1].ToString() + " AND ";
}
sql = sql.Remove(sql.Length - 4);
ExcuteSql(sql);
}
//查询单个数据(ID是主键)
public Dictionary<string, object> SelectByID(string _tableName,int Id)
{
string sql = "SELECT * FROM " + _tableName +" WHERE Id ="+Id;
reader = ExcuteSql(sql);
Dictionary<string, object> dic = new Dictionary<string, object>();
//阅读电子书,翻页
reader.Read();
for (int i = 0; i < reader.FieldCount; i++)
{
dic.Add(reader.GetName(i), reader.GetValue(i));
}
reader.Close();
return dic;
}
//查找所有
public List<Dictionary<string, object>> SelectAll(string _tableName)
{
string sql = "SELECT * FROM " + _tableName;
List<Dictionary<string, object>> dataArr = new List<Dictionary<string, object>>();
reader = ExcuteSql(sql);
while (reader.Read())
{
Dictionary<string, object> data = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
string key = reader.GetName(i);
object value = reader.GetValue(i);
data.Add(key, value);
}
dataArr.Add(data);
}
return dataArr;
}
//按照自定义条件查找单条数据
public Dictionary<string,object> SelectWithCondition(string _tableName,params object[] options)
{
if (options == null || options.Length == 0 || options.Length % 2 == 1)
Debug.LogError("options Length has error!!!");
string sql = "SELECT * FROM " + _tableName + " WHERE ";
Dictionary<string, object> dic = new Dictionary<string, object>();
for(int i=0;i< options.Length;i+=2)
{
sql += options[i] + "= '" + options[i + 1]+"' AND ";
}
sql = sql.Remove(sql.Length-4);
reader = ExcuteSql(sql);
reader.Read();
for(int i=0;i<reader.FieldCount;i++)
{
string key = reader.GetName(i);
object value = reader.GetValue(i);
dic.Add(key, value);
}
return dic;
}
//按照自定义条件查找整张表数据
public List<Dictionary<string, object>> SelectAllWithCondition(string _tableName, params object[] options)
{
if (options == null || options.Length == 0 || options.Length % 2 == 1)
Debug.LogError("options Length has error!!!");
string sql = "SELECT * FROM " + _tableName + " WHERE ";
List<Dictionary<string, object>> dataArr = new List<Dictionary<string, object>>();
for (int i = 0; i < options.Length; i += 2)
{
sql += options[i] + "= '" + options[i + 1] + "' AND ";
}
sql = sql.Remove(sql.Length - 4);
reader = ExcuteSql(sql);
while (reader.Read())
{
Dictionary<string, object> data = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
string key = reader.GetName(i);
object value = reader.GetValue(i);
data.Add(key, value);
}
dataArr.Add(data);
}
return dataArr;
}
//执行数据库语句
SqliteDataReader ExcuteSql(string _sql)
{
Debug.Log("Excuted Sql :" + _sql);
//创建数据库连接命令(事务管理、命令管理:向数据库发送指令)
command = connection.CreateCommand();
//设置命令语句
command.CommandText = _sql;
//执行命令后 返回 阅读器信息
using (reader = command.ExecuteReader())
{
return reader;
}
}
}
2.实体类
数据库读出的数据,最终都是要转到实体类上的,一般两种方法:1.是手动转化,2.是通过反射自动赋值
这里为了方便起见,暂时使用了手动转化的方式。
代码如下:
using UnityEngine;
using System.Collections.Generic;
public class SqlDataBase
{
public virtual SqlDataBase InitWithSqlData(Dictionary<string, object> _data)
{
return null;
}
}
public class Player : SqlDataBase
{
public int id;
public string name;
public int level;
public int hp;
public int ep;
public int exp;
//数据库中读出的字典数据->实体类
public override SqlDataBase InitWithSqlData(Dictionary<string, object> data)
{
this.id = System.Convert.ToInt32(data["id"]);
this.name = System.Convert.ToString(data["name"]);
this.level = System.Convert.ToInt32(data["level"]);
this.hp = System.Convert.ToInt32(data["hp"]);
this.ep = System.Convert.ToInt32(data["ep"]);
this.exp = System.Convert.ToInt32(data["exp"]);
return this;
}
}
3.DAO类
现在数据库读取方法有了,数据库数据转实体类也有了,但是我现在想获取一个最简单的Player Id为1的数据,还是要写好几行代码。
因此一般开发当中,都需要一个DAO(Data Access Object)中间工具类DAO类,来帮助我们,说白了,DAO就是帮助我们通过一行代码获得我们想要的数据实体。
using UnityEngine;
using System.Collections.Generic;
public class DAO<T> where T :SqlDataBase,new() {
public static T GetById(int id)
{
return GetInfoWithCondition(typeof(T).Name, new object[] { "id", id });
}
public static List<T> GetAllInfos()
{
string tableName = typeof(T).ToString().ToLower();
List<Dictionary<string, object>> resultList = SqlManager.Instance.SelectAll(tableName);
if (resultList.Count == 0)
{
return default(List<T>);
}
List<T> t = new List<T>();
for (int i = 0; i < resultList.Count; i++)
{
T tmp = new T();
tmp.InitWithSqlData(resultList[i]);
t.Add(tmp);
}
return t;
}
public static T GetInfoWithCondition(string tableName, object[] options)
{
UnityEngine.Assertions.Assert.IsTrue(options.Length % 2 == 0, "[DAO GetInfoFromTable] options error.");
Dictionary<string, object> resultList = SqlManager.Instance.SelectWithCondition(tableName,options);
T tmp = new T();
tmp.InitWithSqlData(resultList);
return tmp;
}
public static List<T> GetInfosWithCondition(string tableName, object[] options)
{
UnityEngine.Assertions.Assert.IsTrue(options.Length % 2 == 0, "[DAO GetInfoFromTable] options error.");
List<Dictionary<string, object>> resultList = SqlManager.Instance.SelectAllWithCondition(tableName, options);
if (resultList.Count == 0)
{
return default(List<T>);
}
List<T> t = new List<T>();
for (int i = 0; i < resultList.Count; i++)
{
T tmp = new T();
tmp.InitWithSqlData(resultList[i]);
t.Add(tmp);
}
return t;
}
}
4.总结
那么经过上面的努力,现在我们想查询一个player或者player列表,就只需要一行代码
//查询101玩家
var p = DAO<Player>.GetById(101)
//查询所有玩家
var list = DAO<Player>.GetAllInfos()
希望这篇文章对你有所帮助!!!