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( nulltrue);
                }
                 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的實現。


歡迎路過的吐槽。。。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM