MVC数据封装

数据是一个软件
MVC是开发过程中最常见的开发模式,在一个游戏或者一个应用开发过程中其实看不见的数据才是中间的灵魂和关键。无论是根据网络数据回调后反序列化还是直接从本地文件中读取数据,软件运行过程其实都是数据在中间运转。

数据怎么来的呢?

策划会将数据写成Excel 表,你需要做的就是把数据读取出来。
在这里插入图片描述
Excel数据有了,现在就需要读取数据了。可是Unity直接读取Excel数据吗??数据就这么明白的袒露出来吗??

这里我们需要开发一个工具把Excel数据读取出来,然后加密或者混淆等方式写成自定义文件类型,Unity那边读取这个自定义类型文件就Ok了。

开发工具可以使用Python或者WinForm等方式,操作Excel数据需要Microsoft.Office.Interop.Excel.dll这个类库。下面直接上代码

#region ReadData 读取数据
/// <summary>
/// 读取数据
/// </summary>
/// <param name="path"></param>
private void ReadData(string path)
{
    if (string.IsNullOrEmpty(path)) return;
    string tableName = GetFirstSheetNameFromExcelFileName(path, 1);

    string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + path + ";" + "Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";

    DataTable dt = null;
    using (OleDbConnection conn = new OleDbConnection(strConn))
    {
        conn.Open();
        string strExcel = "";
        OleDbDataAdapter myCommand = null;
        DataSet ds = null;
        strExcel = string.Format("select * from [{0}$]", tableName);
        myCommand = new OleDbDataAdapter(strExcel, strConn);
        ds = new DataSet();
        myCommand.Fill(ds, "table1");
        dt = ds.Tables[0];
        myCommand.Dispose();
    }
    CreateData(path, dt);
}
#endregion

#region CreateData 生成加密后的文件
/// <summary>
/// 生成加密后的文件
/// </summary>
/// <param name="path"></param>
/// <param name="dt"></param>
private void CreateData(string path, DataTable dt)
{
    //数据格式 行数 列数 二维数组每项的值 这里不做判断 都用string存储

    string filePath = path.Substring(0, path.LastIndexOf('\\') + 1);
    string fileFullName = path.Substring(path.LastIndexOf('\\') + 1);
    string fileName = fileFullName.Substring(0, fileFullName.LastIndexOf('.'));

    byte[] buffer = null;
    string[,] dataArr = null;

    using (MemoryStreamBuffer ms = new MemoryStreamBuffer())
    {
        int row = dt.Rows.Count;
        int columns = dt.Columns.Count;

        dataArr = new string[columns, 3];

        ms.WriteInt(row);
        ms.WriteInt(columns);
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < columns; j++)
            {
                if (i < 3)
                {
                    dataArr[j, i] = dt.Rows[i][j].ToString().Trim();
                }
                ms.WriteUTF8String(dt.Rows[i][j].ToString().Trim());
            }
        }
        buffer = ms.ToArray();
    }

    //------------------
    //第1步:xor加密
    //------------------
    int iScaleLen = xorScale.Length;
    for (int i = 0; i < buffer.Length; i++)
    {
        buffer[i] = (byte)(buffer[i] ^ xorScale[i % iScaleLen]);
    }

    //------------------
    //第2步:压缩
    //------------------
    //压缩后的字节流
    buffer = ZlibHelper.CompressBytes(buffer);

    //------------------
    //第3步:写入文件
    //------------------
    FileStream fs = new FileStream(string.Format("{0}{1}", filePath, fileName + ".data"), FileMode.Create);
    fs.Write(buffer, 0, buffer.Length);
    fs.Close();
}
#endregion

运行后生成为 .data 类型的文件,Unity端直接加载文件后通过解压,解密后得到Byte[] 数据,然后通过字节流读取出来就Ok了。

抽象封装一个实体类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 数据实体基类
/// </summary>
public class AbstractEntity {
    /// <summary>
    /// 编号
    /// </summary>
    public int Id
    {
        get;
        set;
    }
}

这边的 Id数据编号,可以理解为SQL 中的主键。

好像每一个Excel存储的数据类型都不一样哦,每次手动去写实体类,太麻烦了,怎么办呢? 还是用工具帮忙写一下把。

/// <summary>
/// 创建实体
/// </summary>
private void CreateEntity(string filePath, string fileName, string[,] dataArr)
{
    if (dataArr == null) return;

    if (!Directory.Exists(string.Format("{0}Create", filePath)))
    {
        Directory.CreateDirectory(string.Format("{0}Create", filePath));
    }
    if (!Directory.Exists(string.Format("{0}CreateLua", filePath)))
    {
        Directory.CreateDirectory(string.Format("{0}CreateLua", filePath));
    }
    StringBuilder sbr = new StringBuilder();
    sbr.Append("using System.Collections;\r\n");
    sbr.Append("\r\n");
    sbr.Append("/// <summary>\r\n");
    sbr.AppendFormat("/// {0}实体\r\n", fileName);
    sbr.Append("/// </summary>\r\n");
    sbr.AppendFormat("public partial class {0}Entity : AbstractEntity\r\n", fileName);
    sbr.Append("{\r\n");

    for (int i = 0; i < dataArr.GetLength(0); i++)
    {
        if (i == 0) continue;
        sbr.Append("    /// <summary>\r\n");
        sbr.AppendFormat("    /// {0}\r\n", dataArr[i, 2]);
        sbr.Append("    /// </summary>\r\n");
        sbr.AppendFormat("    public {0} {1} {{ get; set; }}\r\n", dataArr[i, 1], dataArr[i, 0]);
        sbr.Append("\r\n");
    }

    sbr.Append("}\r\n");


    using (FileStream fs = new FileStream(string.Format("{0}Create/{1}Entity.cs", filePath, fileName), FileMode.Create))
    {
        using (StreamWriter sw = new StreamWriter(fs))
        {
            sw.Write(sbr.ToString());
        }
    }
}

封装数据Model层,这里的Model主要适用于列表类型的数据。实例化操作Entity的数据管理类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class AbstractDBModel<T,P>
    where T:class,new()
    where P:AbstractEntity
{
    protected List<P> m_List;
    protected Dictionary<int, P> m_dic;
    public AbstractDBModel()
    {
        m_List = new List<P>();
        m_dic = new Dictionary<int, P>();
        LoadData();
    }
    public static T instance;
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new T();
               // instance.;
            }
            return instance;
        }
    }
    //获取文件名称
    protected abstract string FileName { get; }
    //获取实体
    protected abstract P MakeEntity(GameDataTableParser parse);
    /// <summary>
    /// 加载数据
    /// </summary>
    private void LoadData()
    {
        string path = null;
#if DISABLE_ASSETBUNDLE && UNITY_EDITOR
        path = Application.dataPath + "/Download/DataTable/" + FileName;
#else
        path = Application.persistentDataPath + "/Download/DataTable/" + FileName;
#endif

        //读文件
        using (DataTableParser parse = new DataTableParser(path))
        {
            while (!parse.Eof)
            {
                //创建实体
                P p = MakeEntity(parse);
                m_List.Add(p);
                m_dic[p.Id] = p;
                parse.Next();
            }
        }
        //解压缩
    }
    /// <summary>
    /// 获取数据列表
    /// </summary>
    /// <returns></returns>
    public List<P> GetList()
    {
        return m_List;
    }
    /// <summary>
    /// 根据编号查询
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public P Get(int id)
    {
        if (m_dic.ContainsKey(id))
        {
            return m_dic[id];
        }
        return null;
    }
}

利用工具生成数据管理类

/// <summary>
/// 创建数据管理类
/// </summary>
private void CreateDBModel(string filePath, string fileName, string[,] dataArr)
{
	if (dataArr == null) return;
	
	if (!Directory.Exists(string.Format("{0}Create", filePath)))
	{
	    Directory.CreateDirectory(string.Format("{0}Create", filePath));
	}
	
	StringBuilder sbr = new StringBuilder();
	sbr.Append("\r\n");
	sbr.Append("//===================================================\r\n");
	sbr.AppendFormat("//创建时间:{0}\r\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
	sbr.Append("//===================================================\r\n");
	sbr.Append("using System.Collections;\r\n");
	sbr.Append("using System.Collections.Generic;\r\n");
	sbr.Append("using System;\r\n");
	sbr.Append("\r\n");
	sbr.Append("/// <summary>\r\n");
	sbr.AppendFormat("/// {0}数据管理\r\n", fileName);
	sbr.Append("/// </summary>\r\n");
	sbr.AppendFormat("public partial class {0}DBModel : AbstractDBModel<{0}DBModel, {0}Entity>\r\n", fileName);
	sbr.Append("{\r\n");
	sbr.Append("    /// <summary>\r\n");
	sbr.Append("    /// 文件名称\r\n");
	sbr.Append("    /// </summary>\r\n");
	sbr.AppendFormat("    protected override string FileName {{ get {{ return \"{0}.data\"; }} }}\r\n", fileName);
	sbr.Append("\r\n");
	sbr.Append("    /// <summary>\r\n");
	sbr.Append("    /// 创建实体\r\n");
	sbr.Append("    /// </summary>\r\n");
	sbr.Append("    /// <param name=\"parse\"></param>\r\n");
	sbr.Append("    /// <returns></returns>\r\n");
	sbr.AppendFormat("    protected override {0}Entity MakeEntity(GameDataTableParser parse)\r\n", fileName);
	sbr.Append("    {\r\n");
	sbr.AppendFormat("        {0}Entity entity = new {0}Entity();\r\n", fileName);
	
	for (int i = 0; i < dataArr.GetLength(0); i++)
	{
	    sbr.AppendFormat("        entity.{0} = parse.GetFieldValue(\"{0}\"){1};\r\n", dataArr[i, 0], ChangeTypeName(dataArr[i, 1]));
	}
	sbr.Append("        return entity;\r\n");
	sbr.Append("    }\r\n");
	sbr.Append("}\r\n");
	
	using (FileStream fs = new FileStream(string.Format("{0}Create/{1}DBModel.cs", filePath, fileName), FileMode.Create))
	{
	    using (StreamWriter sw = new StreamWriter(fs))
	    {
	        sw.Write(sbr.ToString());
	    }
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值