CYQ.Data 数据层框架CYQ.Data 是一款由路过秋天创作的支持多数据库应用[Txt,Xml,Access,MSSQL,Oracle,SQLite,MySql]的底层数据库操作类库,使用本类库可以轻松快速开发项目(QQ群:6033006)。 |
CYQ.Data V5文本数据库技术原理解密
框架原理 |
|
|
| #楼主 |
前言: 这两天有点感冒状态,除了以前折腾 微博粉丝精灵 腾到三更,最近也在折腾个别工具到四更,偶尔心来心潮,赶紧写写文章,最近有很多朋友对CYQ.Data V5里的文本数据库感兴趣,这里就给大伙说下文本数据库技术原理,给大伙解下密。
CYQ.Data 框架的稳定与前进: CYQ.Data 对于V4系列,版本号就在V4.55版本就不再提高了,主要是为了保留一个最稳定的版本,基本除了Bug修正,不会再有大于V4.N的版本号出现了。 而V5版本,这一两年来,事实上,代码改动相当大,内部类的结构也调整不少,由于功能的新增加导致和改动,被记录的就有四五十项,没记录的数不清了,不过V5在各项目中沉淀了也近一年了,稳定性也很强。 CYQ.Data 文本数据库: 以前写过相关的文章:周末一起用文本数据库玩玩Code First 对于文本数据库的应用,在原来的 OAuth2 登陆组件,就应用上了,用户存储AccessToken和对应账号,不知道大伙注意到了没有。 这里我再举昨天发布的 CYQ.Data.ProjectTool 项目配置工具发布(包源码),保存用户配置的也是文本数据库。 CYQ.Data 文本数据库技术原理: 先看图片:
简单工程描述: 在这个项目中,主要是读取表结构,然后生成相应的枚举类,或实体类,同时需要保存用户的配置,根据配置名称,允许保存多个配置项,而且每次开启,需要还原用户最新的配置项。 用什么来保存配置? 在以前,我用了App.config来保存配置,当然也可以用Xml,ini文件,不过,代码写起来都相对比较费力,人总是在使用某些东西觉的费力麻烦的时候,就会出一种方案来解决它们,所以,文本数据库就是这样一种简单的方案。 下面用源码里的部分代码片断来解密文本数据库的本质: 这个简单的工程,事实包含了数据库基本的增删改查操作: 1:添加用户配置。 2:同配置名,更新用户配置。 3:删除用户配置(估计被我遗忘了,没加上这功能) 4:从所有配置中,查询出被标识为IsMain=true的数据,并还原为默认配置。 项目里建了一个ProjectConfig实体类,来个CodeFirst: 这实体多了一个ORM继承,让它具备ORM的基础功能: 构造函数要指定表名和数据库链接(可以是配置名,内部判断的依据是有没有空格,没空格则到web.config取,有空格当成链接)
实体类代码如下: CYQ.Data.ProjectTool
namespace CYQ.Data.ProjectTool
{ public class ProjectConfig : CYQ.Data.Orm.OrmBase { public ProjectConfig() { base.SetInit(this, "ProjectConfig", "Txt Path={0}"); } private int _ID; /// <summary> /// 标识 /// </summary> public int ID { get { return _ID; } set { _ID = value; } } private string _Name; /// <summary> /// 配置名称 /// </summary> public string Name { get { return _Name; } set { _Name = value; } } private string _Conn; /// <summary> /// 链接字符串 /// </summary> public string Conn { get { return _Conn; } set { _Conn = value; } } private string _DBType; /// <summary> /// 数据库类型 /// </summary> public string DBType { get { return _DBType; } set { _DBType = value; } } private bool _MutilDatabase; /// <summary> /// 支持多数据库模式 /// </summary> public bool MutilDatabase { get { return _MutilDatabase; } set { _MutilDatabase = value; } } private string _ProjectPath; public string ProjectPath { get { return _ProjectPath; } set { _ProjectPath = value; } } private bool _IsMain; public bool IsMain { get { return _IsMain; } set { _IsMain = value; } } private string _BuildMode; /// <summary> /// 创建模式(枚举模式;ORM实体类模式) /// </summary> public string BuildMode { get { return _BuildMode; } set { _BuildMode = value; } } private string _NameSpace; /// <summary> /// 默认的名称空间 /// </summary> public string NameSpace { get { return _NameSpace; } set { _NameSpace = value; } } } PS:如果你数据库链接从Txt Path改成Xml Path,你会发现,存储的格式变成Xml。
看一段增加配置的代码片断: 在用户点击“测试链接”或“生成文件”时,如果检测到链接是成功的,则自动保存当前配置信息,代码如下: string SaveConfig() {
string name = ddlName.Text.Trim(); if (string.IsNullOrEmpty(name)) { name = "DefaultConn"; } ResetMainState(); using (ProjectConfig config = new ProjectConfig()) { config.SetAutoParentControl(gbConn, gbBuild); if (config.Fill("Name='" + name + "'")) { config.IsMain = true; config.Update(null, true); } else { config.IsMain = true; if (config.Insert(true)) { ddlName.Items.Add(name); } } } return name; } 看看实体类New的这一行代码: using (ProjectConfig config = new ProjectConfig())
using 语法: 不多解释了,结束的时候,它自动会调用disponse方法,自动关闭并释放相关资源。
构造函数New初始化: 系统会获取实体类上的属性成员,组成一个表结构,然后写到数据库链接里指定的路径。 你运行软件后,会自动发下在指定的目录下多了一个文件:ProjectConfig.ts 里面存储了表的结构,内容如下: ID,Int,False,False,0,;
Name,NVarChar,False,True,0,;
Conn,NVarChar,False,True,0,;
DBType,NVarChar,False,True,0,;
MutilDatabase,Bit,False,True,0,;
ProjectPath,NVarChar,False,True,0,;
IsMain,Bit,False,True,0,;
BuildMode,NVarChar,False,True,0,; NameSpace,NVarChar,False,True,0,; 简单说明: 表结构存储格式为:名称,类型,允许为空,是否只读,长度,默认值。 对于文本数据库,就是创建了“表名.ts",如果是其它数据库链接,就会直接在数据库创建相应的表。 后面的属性赋值,和ORM的基础操作方法,我们简单略过: 这里使用和UI结合的方式取值:config.SetAutoParentControl(gbConn, gbBuild); 自动多两个GroupBox里的子控件里取值。 而IsMain属性,是不在控件里出现的,所以需要单独赋值。 通过和UI结合,在还原配置项的时候,也只要一句SetToAll(),就搞定了: 源码里有这样一段代码,根据配置名,还原所有配置,看一眼就可以了: void LoadConfig(string name)
{ if (!string.IsNullOrEmpty(name)) { using (ProjectConfig config = new ProjectConfig()) { if (config.Fill("Name='" + name + "'")) { config.SetToAll(gbConn, gbBuild); } } } } 对于文本数据库,刚才只是说自动生成了表结构,存储为“*.ts"文件了。 对于数据的存储呢? CYQ.Data 有两个类: 1:JsonHelper:和Json打交道的类。 2:MDataTalle:内存表,功能很强大,具备和Json或Xml加载与输出的功能。 文本数据库的实现,正是基于这个两个类。 在存储时,如果有多个文本,则是多个Static MDataTable 通过MDataTable与Json(或Xml)的交互,加载与输入来实现。 所以若运行后,基本可以看到这个文件:ProjectConfig.txt,里面存储着json文件如下:
{"ID":"System.Int32","Name":"System.String","Conn":"System.String","DBType":"System.String","MutilDatabase":"System.Boolean","ProjectPath":"System.String","IsMain":"System.Boolean","BuildMode":"System.String","NameSpace":"System.String"},
{"ID":"1","Name":"DefaultConn","Conn":"server=.;database=qblog;uid=sa;pwd=123456","DBType":"Mssql","MutilDatabase":"False","ProjectPath":"","IsMain":"True","BuildMode":"实体型(ORM操作方式)","NameSpace":"Web.Entity"} 简单说明: 第一行,根据某些情况,可能存储数据类型,这是为丢失表结构的情况下,从Json还原为MDataTable时,仍能有基本的数据结构存在。 当然第一行也可能直接就是json数据了,系统根据某些特定标识来识别第一行是架构还是数据。 文件数据库的增删改查原理: 如果你对DataTable熟悉,相信也对MDataTable也熟悉,文本数据库的增删改查,全在MDataTable里进行。 框架的统一:分页与Sql查询语法: 对于文本而言,存储的结果就是json,为了多数据的统一,使的它必需具备基础的数据库应有的功能,分页与sql语句语法的查询。 为此,我对MDataTable进行了一个重要功能的补充,对sql语句进行解析,然后进行列的比较,再对数据行进行自定义排序,从而筛选出最终结果。 为此,MDataTable事实上,就是一个具备分页,查询功能的强大表类,而且可以脱离数据库,拿到数据后,可以继续再进行分页查询操作。 MDataTalle的其它特性: 同时,MDataTable还具备基础的批量插入和更新功能,这个功能很要(CYQ.DBImport 多数据库数据互导功能,事实上也是用了这个功能,从一个数据库查询出一个MDataTable,然后调用AccpertChange函数,就可以批量转移到其它数据库了,几行代码就实现了,非常方便)
总结: 基本文件数据库到这里也没啥秘密了: 1:根据实体类自动生成表结构(如果已存在表结构,自动加载)。 2:存储格式是Json,依赖JsonHelper和MDataTable进行加载和写入互动。 3:增删改查,实际是依赖于MDataTable,对数据行的增删改查。 4:CodeFirst模式,本质是基于MAction的实现。
|
发表评论
论坛公告
帖子搜索
最新帖子
最新评论
- 请教博主。我mysql的提示 V5.7.7.4 MySql.xxxx:check the tablename "tbl_site_info" is exist? error:ExeDataReader():Expression #1 of ORDER BY clause is not in SELECT list, references column 'information_schema.s1.ORDINAL_POSITION' which is not in SELECT list; this is incompatible with DISTINCT 配置如下: <?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="Conn" connectionString="host=192.168.3.101;Port=3306;Database=xxxxx;uid=root;pwd=2017" providerName="MySql.Data.MySqlClient"/> </connectionStrings> </configuration>
- 查询语句有点问题,软件启动时查询语句可以从数据库查询出数据,软件一直运行时无论怎么修改数据库,查询出来的还是老数据,不知道是为什么
- 我语句中用到了union all而且两个查询都有查询条件,action.select总是不成功,不知道有没有什么好的解决办法,谢谢
- 大神,如果我想通过一个对象(从数据映射过来的)要插入的话,我需要遍历字段然后每个set一下吗?有没有更好的方法??
- 真心好用,想问下秋天直接拼写sql怕注入吗
- V4.5后,好多方法都改变了,求来个新的日志帮助
- 請問大神V5源碼要多少錢 我是和交流過的
- 楼主,,从数据库里查出来并绑定datagridview,但是显示的都是数据库里的英文名,怎么改??好纠结啊这个。。。。
- 我想问一下,主从表添加怎样处理
- 10年就过了!!!!