定制數據層
2024-07-21 02:08:37
供稿:網友
定制數據層
關鍵字:數據層,訪問,元數據,數據訪問模型
撰寫:●⌒●┒ [email protected] 引用請注明出處
時間:2003年8月
摘要:在一個分層的系統中,數據層承擔的任務是為系統提供需要的數據。在承上啟下的過程中,系統的變更,尤其是系統數據要求的變更會讓數據層忙的不亦樂乎。為此在痛苦的變更之后,我選擇了數據訪問模型,將元數據引入到數據層。使之有極強的擴展能力,變更能力。本文就將介紹一個基本無需編程的數據層。
如果您使用的是小系統或已經決定使用快速綁定數據庫表。本文可能對您不太合適。
概念的提出
在一個稍有規模的系統中,目前一般會使用分層的設計。數據層的概念由此產生,為系統提供必須的數據,屏蔽數據存取,使用簡單易用的接口實現數據操作。它將實現create,read,update,delete(crud)的操作來提供給上層……等等。
數據是一個軟件系統的核心。絕大多數的數據保存在商業數據庫中,一般無需我們為此添油加醋。數據層則是系統與數據庫打交道的一個,也應該是唯一的一個地方。
然而,系統的變更幾乎無法避免。用戶現場提出,需求變更等等幾乎無法完全避免。同時一個開發好的系統也可能需要使用不同的數據庫。變既然無法避免,不如積極面對。引入數據訪問模型使得變更在數據層不用更改代碼,甚至一個數據層組件可以適應不同的系統。也就是說--數據層的編程工作量幾乎已經沒有。
數據層模型
上圖是一個部署模型。如圖:數據層被分成了數據提供層和數據訪問層,和一個數據訪問元數據。下面分別介紹這四個文件的作用:
數據訪問元數據:
描述數據的存取方法的數據,為系統的每一個存取數據邏輯提供描述,并使用數據訪問點命名此訪問邏輯,元數據存于數據庫中。
通用數據訪問層:
是一個組件,管理數據庫驅動、屏蔽數據庫差別、為上層提供簡單一致的接口執行調用。
通用數據提供組件:
使用通用數據訪問層執行數據的crud操作,使用數據訪問元數據控制數據調用指令。
專用數據提供組件:
如果數據訪問元數據構建的數據訪問模型構建得不充分,需要此組件提供必要的功能補充。
數據訪問模型
此模型由數據訪問元數據來描述,因此元數據的定義需要功力。一方面:數據訪問元數據越完備,通用數據提供組件功能就越強。兼容性也越好,但另一方面,模型比較細膩會讓通用數據提供組件的編程比較復雜,因此需要權衡。
在一定的權衡后,我給出了如下的定義,下列定義已經足以滿足一般的需要:
它將存在兩部分。數據庫和本地緩存。
數據庫中保存在數據訪問元數據表dataaccessmeta。
本地緩存包含dataaccessmeta表的緩存,還有數據庫的架構信息,包括,數據庫中有什么表,表中有幾個字段,表中字段的屬性,表間的約束關系等。
列名域說明idint(not null)主鍵、唯一標識符,默認自增1querynamevarchar(128)(not null) 唯一,數據訪問點名稱,即應用層的調用的傳入參數typeint(not null)保留 訪問類別,默認0,returntypeint(not null)0:多個數據表表示一個數據集(默認)1:由多表合成一個表的數據集(動態視圖)transactionint(not null)0:不需要事務支持 (默認)1:需要事務支持sqlvarchar(512)存儲sql語句,可變參數值在字段名前面加@號表示。storeprocedurevarchar(64)存儲過程名稱viewvarchar(64)視圖名稱table_1varchar(32)表名fieldname_1varchar(256)table_1字段名(指定要訪問的字段)空,將返回表中所有字段。table_2varchar(32)表名fieldname_2varchar(256) table_2字段名(指定要訪問的字段)空,將返回表中所有字段。table_3varchar(32)表名fieldname_3varchar(256)table_3字段名(指定要訪問的字段)空,將返回表中所有字段。table_4varchar(32)表名fieldname_4varchar(256)table_4字段名(指定要訪問的字段)空,將返回表中所有字段。table_5varchar(32)表名fieldname_5varchar(256)table_5字段名(指定要訪問的字段)空,將返回表中所有字段table_6varchar(32)表名fieldname_6varchar(256)table_6字段名(指定要訪問的字段)空,將返回表中所有字段
說明:
queryname為數據存取邏輯的別名。上層通過此別名來調用相應元數據 表中優先級從上到下(對于允許為空的字段,但它存在時,忽略其他。)比如sql字段存在,將忽略storeprocedure及以下字段。 在從表讀數據時從table_1讀到table_6,保存時倒序。 sql字段內容可以以傳入入參數方式表示,如"select * from table where [email protected]"即為一個合法的命令文本,我們可以以參數形式動態為@username賦值。 當returntype 為1時(把多表合成一表),各表之間必須要有且只有一個外鍵關聯,查找關系的優先級從table_1 到 table_6。表連接也是相同順序,因此注意表的先后關系 此外,數據庫中必須還要有一張版本表來判別元數據的版本問題。
本地緩存主要為了效率。至少包含三部分,上面的數據訪問元數據緩存,數據庫的架構緩存,版本緩存,即至少3個文件。
通用數據訪問層
設計原則:
簡化data access logic component中對數據庫的操作。 數據存取進行集中處理,有利屏蔽數據庫之間的差別。管理數據源。管理數據庫的認證。管理事務性的操作。管理數據庫連接。
應提供的接口有:
setconnectpropety() //設置連接屬性 setdbtype() //設置數據庫類型,比如oracle,sql server execsql()//執行sql語句,注意需要根據數據庫類型解析成對應的語句。 update()//將數據集寫入數據庫 transactiong() //控制事務處理的相關函數 getdbtablename()//得到數據庫中的所有表名 getdbforeignkey()//得到數據庫中的所有外鍵關系
通用數據提供組件
設計原則:
僅返回需要的數據。 為不同的調用提供一致接口。 為輸入輸出參數提供簡單的映射和轉換。使上層不用關心數據存儲。 暴露元數據的接口。查詢參數,結果集的描述等。 處理一個主表和相關聯的表。 執行優化操作和鎖定等數據庫操作。 緩存數據和非事務性的查詢結果。 在使用分布式或多數據庫的系統下,提供動態的數據庫路由。 不要為每個事務提供數據庫的事務支持,節約數據庫資源。 不應該初始化有交集的事務,因為可能會出現多處同時更新的情況,引發矛盾。 不要在各個方法調用時維持狀態。 不要為每個表設計一個數據訪問點,應該為每個系統數據需求提供。 本組件奉行一個原則,"系統不應當知道數據從何而來,但程序員應該非常熟悉。"
內部對象:
元數據管理類:負責元數據的更新,緩存,讀取,管理元數據內存緩沖,對效率的要求極高。 數據提供類:負責解析數據訪問元數據,并將解析結果傳入數據訪問層。
應提供的接口有:
setconnectpropety() //設置連接屬性 getdataset(straccesspoint,strfilter,strfield)//獲得數據集。其中straccesspoint為數據訪問點名稱 update() //把數據集更新到數據庫 getaccesspoint()//得到所有的數據訪問點名稱 getfields(straccesspoint) //得到每個數據訪問點可以獲得的字段名 getfieldproperty(straccesspoint,strfieldname) //得到每個字段的屬性
工作過程:
1.檢測元數據和數據庫版本。如更新,下載到本地。
2.將元數據,數據庫架構讀入內存,(約1張表1k的數據量)。
3.等待查詢。
4.查詢時解析元數據,構造需要的sql語句。
5.將sql傳入數據訪問層。
6.得到數據。
7.根據元數據將表間約束填入數據集。
8.返回數據,等待查詢。
結語:
元數據的使用。致使效率上有所降低。所以并不適合對效率要求極高的系統。
我使用ado.net構造了一個本文所描述的數據層。兩人發了5周的時間編碼。應用良好。覺得對大家也許有些幫助。特撰寫此文與大家共勉。
元數據的使用其實并不僅限于數據層,如若把界面,功能元數據結合,大家可以想象將會出現什么結果,只不過數據層的元數據容易歸納而已。
本組件在 http://www.csdn.net/cnshare/soft/19/19227.shtm 已經發布。