博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
提高生产性工具(四) - XML数据库的尝试
阅读量:4624 次
发布时间:2019-06-09

本文共 6625 字,大约阅读时间需要 22 分钟。

首先祝大家新年快乐.身体健康,平安就是福气.

对于一般的个人迷你项目,数据量不大的时候,完全没有必要使用数据库,管理数据使用XML就可以了.

自己尝试写了一个XML数据库,插入1w条小记录,大概3M大小,然后将一半数据进行更新,大约耗时3秒钟.

XML数据库其实就是一个内存数据库,数据都在内存里面,速度不慢.

然后由于是XML序列化的,其实ORM也不需要了.每个数据库文件保存一种格式的数据.

废话不说,上代码

先是数据模型:

/* * Created by SharpDevelop. * User: scs * Date: 2014/12/30 * Time: 14:07 *  * To change this template use Tools | Options | Coding | Edit Standard Headers. */using System;using DevKit.Common;namespace DevKit.HtmlUtility{    ///     /// Description of Class1.    ///     [Serializable]    public class CodeSnap    {        ///         /// 标题        ///         public string Title = string.Empty;        ///         /// 描述        ///         public string Descrpition = string.Empty;        ///         /// 类别        ///         public string Catalog = string.Empty;        ///         /// Tag        ///         public string Tag = string.Empty;        ///         /// 代码        ///         public string Code = string.Empty;        ///         /// 检索        ///         /// 检索关键字        /// 
Boolean Search(string strKeyword) { return false; } }}

数据模型是领域的数据,但是删除标志,更新时间这些数据库使用的字段也是需要的.由于需要序列化,必须打上[Serializable]

///     /// 数据库记录    ///     [Serializable]    public class Model
{ ///
/// 删除标志 /// public Boolean IsDel; ///
/// 统一编号 /// public string DBId; ///
/// 最后更新时间 /// public DateTime LastUpdate; ///
/// 数据 /// public T DataRec; }

最后是数据库引擎的代码,这里用到了深拷贝

 

///     /// 数据库引擎    ///     public class XmlDataBase
{ ///
/// 数据库状态 /// public string Status = "Close"; ///
/// 数据表 /// List
> list = new List
>(); ///
/// 数据库文件 /// string DBfilename = string.Empty; ///
/// 数据库记录数[Without IsDel] /// ///
public int getCount() { return list.Count(x => { return !x.IsDel; }); } ///
/// 数据库记录数[With IsDel] /// ///
public int getCountWithDel() { return list.Count; } ///
/// 新建并且打开数据库 /// ///
public XmlDataBase(string xmlfilename) { DBfilename = xmlfilename; if (System.IO.File.Exists(xmlfilename)) { list = Utility.LoadObjFromXml
>>(DBfilename); } } ///
/// 压缩数据库 /// public void Compress() { var Compresslist = new List
>(); Func
,Boolean> inner = (x) => { return (!x.IsDel); }; Compresslist = list.FindAll(new Predicate
>(inner)); list = Compresslist; Commit(); } ///
/// 添加 /// ///
public void AppendRec(T rec) { var dbrec = new Model
(); dbrec.DBId = Guid.NewGuid().ToString(); dbrec.DataRec = Common.Utility.DeepCopy(rec); dbrec.LastUpdate = DateTime.Now; list.Add(dbrec); } ///
/// 删除 /// ///
public void DelRec(Model
rec) { rec.IsDel = true; UpdateDB(Utility.DeepCopy(rec)); } ///
/// 更新 /// ///
public void UpdataRec(Model
rec) { UpdateDB(Utility.DeepCopy(rec)); } ///
/// 数据的修改 /// ///
传递过来对象的深拷贝 void UpdateDB(Model
rec) { for (int i = 0; i < list.Count; i++) { if (rec.DBId == list[i].DBId) { rec.LastUpdate = DateTime.Now; //不允许内部数据使用外部数据的指针引用 //这里使用深拷贝 list[i] = rec; break; } } } ///
/// 提交更新 /// public void Commit() { Utility.SaveObjAsXml(DBfilename, list); } ///
/// 检索 /// ///
///
数据对象的深拷贝
public List
> Search(Func
SearchMethod) { Func
,Boolean> inner = (x) => { return (SearchMethod(x.DataRec) && !x.IsDel); }; List
> t = new List
>(); foreach (Model
element in list.FindAll(new Predicate
>(inner))) { //这里也是将数据的副本给与外部 t.Add(Utility.DeepCopy(element)); } return t; } }

数据库内部有一个列表,列表里面存放着数据记录,每个数据记录包括[业务数据]和[数据库信息]

数据的读取,给外部的是一个数据的深拷贝,这样的话,保证了外部对于数据的修改不会影响内部数据.

在传统的数据库中,一般都是通过TCP协议交换数据的,所以,数据其实也是一个深拷贝.

读取如此,保存数据也是将列表替换为一个外部对象的深拷贝.

每次保存数据的时候,其实是将所有的数据都写入数据XML文件中,当然,数据量少的前提下,这样做是可以的.

下面是一个使用的例子:数据库的New语句

Common.XmlDataBase
db= new Common.XmlDataBase
(@"C:\中和软件\CodeSnap.xml");;

 

void BtnAppendClick(object sender, EventArgs e)        {            Stopwatch x = new Stopwatch();            x.Start();            for (int i = 0; i < 9999; i++) {                var r = new CodeSnap();                r.Title = "Title" + i.ToString();                r.Descrpition = "Descrpition";                r.Tag = "Tag";                r.Code = "Code";                db.AppendRec(r);            }            db.Commit();            var t = db.Search((m) => {                return true;            });            for (int i = 0; i < t.Count; i++) {                if (i % 2 == 1) {                    t[i].DataRec.Title = "New Title";                    db.UpdataRec(t[i]);                }            }            db.Commit();            x.Stop();            MessageBox.Show(x.Elapsed.ToString());        }

这个只是一个XML数据的雏形,原代码基本上都在这里了.

可以改进的地方大概如下:NameSpace这些XML特有的属性的去除.

现在Key是用GUID的,这个东西也蛮大的,如果不考虑压缩数据库的问题,可以使用数字连番.

(如果使用数字连番的话,由于压缩数据库会改变数据记录数,可能出现主健重复的问题)

其他压缩,例如时间,现在使用标准的DateTime.Now,所以时间也很冗长.以后可以将时间格式化后,保存为文字列.

false
ef65bff8-4951-464d-bd8f-432f1148b9f8
2014-12-31T11:02:43.5750566+08:00

当然,XML也可以换成JSON的,这样的话,数据可以更小,但是JSON操作还不是NET内置的功能,所以暂时不使用.

里面用到的XML操作和深拷贝代码如下

}        ///         /// 保存对象        ///         public static void SaveObjAsXml
(string filename, T Obj) { var xml = new XmlSerializer(typeof(T)); var writer = new StreamWriter(filename); xml.Serialize(writer, Obj); writer.Close(); } ///
/// 读取对象 /// ///
///
///
public static T LoadObjFromXml
(string filename) { var xml = new XmlSerializer(typeof(T)); var reader = new StreamReader(filename); T obj = (T)xml.Deserialize(reader); reader.Close(); return obj; } ///
/// 深拷贝 /// ///
///
public static T DeepCopy
(T obj){ BinaryFormatter bFormatter = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); bFormatter.Serialize(stream, obj); stream.Seek(0, SeekOrigin.Begin); return (T)bFormatter.Deserialize(stream); }

转载于:https://www.cnblogs.com/TextEditor/p/4195361.html

你可能感兴趣的文章
Modified Least Square Method and Ransan Method to Fit Circle from Data
查看>>
JavaScript显示星期几
查看>>
thinkphp5命名规范
查看>>
设计模式六大原则
查看>>
centos7 --ngnix 常用命令:
查看>>
flask+jsonp跨域前后台交互(接口初体验)
查看>>
Eclipse+Maven+springmvc+HelloWorld--Eclipse Maven springMVC第一个HelloWorld吐血配置整理
查看>>
传Windows 8.1系统将重新加入开始按钮
查看>>
C# 自定义异常的方法源码演示及说明
查看>>
输出与输出:putchar() getchar() printf() scanf() puts() gets() sscanf()
查看>>
文档翻译-Minimizing your app's Memory Footprint
查看>>
[Unity优化]批处理01:Statistics窗口
查看>>
自然数的拆分(DFS)
查看>>
nodejs websocket
查看>>
SQLAlchemy_定义(一对一/一对多/多对多)关系
查看>>
添加远程库
查看>>
iOS Animation 学习(3)
查看>>
正则化方法:L1和L2 regularization、数据集扩增、dropout
查看>>
Hadoop学习笔记3---安装并运行Hadoop
查看>>
ASP.NET MVC性能优化(实际项目中)
查看>>