Unity Sqlite数据库操作

在Unity中使用sqlite的教程有很多。 包括:

研究院之使用C#语言建立本地数据库(二十三)

游戏开发之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()

 

希望这篇文章对你有所帮助!!!
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TxNet.Ltd.

你的赞同是对我的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值