充血模型的ORM能作什麼?——ORM組件XCode(十八般武藝)

ORM組件XCode(十八般武藝)html

以前,XCode老是若隱若現,耐性好的同窗想知道它還有啥特色,沉不住氣的則認爲不過是CURD耳!程序員

 

XCode開發模式是靈魂,XCode組件經過具體實現對其支持!數據庫

 

XCode的特色以下:數組

0、基本的CURD功能緩存

實在想不出來不支持CURD的ORM算不算ORM;也實在想不出來僅有CURD的ORM算不算ORM。於是,這是0號功能!服務器

XCode的CURD經過反射實體類生成查詢和操做SQL實現,數據庫結構信息經過特性附在實體類上。之因此選擇SQL而不是DbCommand,由於XCode的實體層和數據訪問層是分開的,目前是爲了實現一級緩存,未來會在這裏實現分佈式數據訪問。多線程

一、完美支持ObjectDataSource架構

XCode實現充血模型(脹血模型)的實體類,提供ObjectDataSource須要的全部方法和參數,特別支持分頁和排序功能!併發

詳見《與ObjectDataSource共舞》異步

二、全面分頁支持

只有從小處開始培營養頁的思想,任何查詢都指定所需獲取數據範圍,才能保證系統數據變大時系統不會拓機。

XCode的分頁以任意查詢語句爲基礎,支持統計等很是複雜的查詢分頁。而且會根據當前數據庫類型以及版本選擇最佳分頁方案。

詳見《撬動千萬級數據》

三、實體集合支持

實體集合EntityList繼承自List,提供了實體的批量操做。實際上仍是經過遍歷集合逐個進行實體操做,由於充血模型的實體類多是經過重載修改CURD的行爲,因此不能使用一個SQL語句操做一批實體,XCode不會作這種可能會影響使用的小把戲。

實體集合還提供了一些方便查詢和排序的簡便方法,實體緩存中將會大量使用。

四、萬能的一級緩存

一級緩存由數據訪問層實現,以查詢SQL爲鍵,返回的數據集爲值,查詢的表名數組爲依賴項,進行緩存。執行SQL時一樣須要指定影響的表名數組,從而清空全部影響到的緩存。

緩存生命週期分爲請求級、按期和永久三種。若是隻有當前應用系統使用該數據庫,而且服務器內存足夠大,能夠開啓永久緩存,在數據沒有更新時,基本緩存在內存中,適用於網站;通常設定一個緩存過時期限,按期清理緩存,適用於內存不是很足,或者容許數據更新有必定延後的分佈式系統;若是上面兩種均不合適,而又須要提升系統響應速度時,能夠採用請求級緩存,在該次頁面請求生命週期內對數據進行緩存,特別適用於在不一樣地方進行相同查詢的場合(有時候是程序員功力不夠寫錯的)。

XCode的開發模式建議使用盡量簡單的單表查詢,實際大部分查詢都是簡單SQL語句,緩存命中率很高!

五、漂亮的實體緩存

實體緩存又成爲二級緩存。儘管有了一級緩存,但它只是緩存了數據集而已,使用的時候仍是要加載數據集成爲實體集合。

實體緩存經過指定一個查詢實體集合的方法,通常是查詢本表全部實體的FindAll()方法,把查詢返回的實體集合緩存起來(默認緩存一分鐘),供上層代碼使用。取數據的過程徹底是隱式進行,實體緩存經過提供一個靜態實體集合供上層代碼查詢,實體集合屬性內部進行查詢數據和緩存過時檢查等操做。查詢方法經過委託傳遞,還有參數能夠指定是否異步獲取緩存數據。

總之,使用實體緩存就是使用一個靜態的實體集合屬性(大多數時候使用默認配置,因此不須要配置),進行查詢排序等操做,無需關心緩存的具體實現。固然,對實體進行修改操做時將會清空緩存,保證數據的新鮮性。

單表數據量不大(建議1000如下,不超過10000),而且極少改動的數據表使用實體緩存。好比權限、角色、菜單、系統參數等使用很是頻繁的數據。實體緩存的命中率能夠高達99.98%

六、飄逸的單對象緩存

單對象緩存又層三級緩存,由於它通常構建於二級緩存之上。對於數據量大(大概幾萬到幾十萬),而且查詢又很是頻繁的數據表,任意兩行數據之間關係不大時,能夠酌情使用單對象緩存。好比會員表,通常會根據帳號進行查找,而且很頻繁,此時能夠以帳號爲鍵,會員對象爲值,對數據進行緩存。設置與實體緩存相似。取數據時先去緩存中找,有則直接返回,沒有則調用預設的方法進行查詢,而且緩存起來。

單對象緩存裏面的實體對象,修改數據時,如非必要,不要手工調用更新方法,單對象緩存有自動保存的功能。該特性適用於更新很是頻繁的場合,好比在線用戶表,可讓屢次更新積累在一塊兒,而後最後自動更新一下。

七、出色的性能

XCode不支持多表查詢,通常的多表關聯查詢均可以拆分紅爲1+X的屢次單表查詢。好比學生和班級的關聯查詢,能夠先查10個學生信息,再分別查他們的班級信息,就成了1+10=11次單表查詢。每一次單表查詢確定會比多表關聯查詢要快,可是11次單表查詢不少時候都會比一次多表關聯查詢慢。

回過頭來看看上面的緩存,若是這10個學生是同班,那麼在一級緩存的做用下,實際查詢數據庫將會是1+1=2,後面9次班級查詢被一級緩存攔截了。在高併發的系統中,後面這個1就趨向於0了,由於緩存是全局共享的。

再來看看實體緩存,一個學校的班級不會不少,符合條件使用實體緩存。也就是一次性讀取全部班級信息,緩存到實體集合中。即便在最糟糕的狀況下,10個學生都處於不一樣班級,實體緩存也是百分百命中,實際查詢僅僅是對學生表的單表查詢,此時確定比多表關聯查詢快。

在學生資料界面等地方,學生表查詢是很是頻繁的。顯然,這是一個很是適用單實體緩存的場合。學生附屬屬性(關聯表)等信息,能夠經過擴展屬性「掛」在學生實體對象上,「享受」到緩存的待遇。

數據庫層面也有一個緩存,能夠算是0級緩存吧。咱們全部的查詢都是單表查詢,對數據庫而言很是簡單,同時,由於簡單的SQL,數據庫緩存命中率極高,而且很是便於創建索引進行優化。

基於分頁和緩存,XCode提供了一套高性能的解決方案,這種方案遠勝於傳統的多表關聯查詢,而且是系統併發越高,這種優點越明顯。

八、髒數據支持

在更新數據的時候,每每業務需求是隻更新咱們修改過的數據。好比會員資料修改表單,能夠設置會員信息等資料,可是不能修改最後登陸時間。這個時候,咱們就須要知道哪一個屬性的數據被咱們修改過!

XCode的實體類中,每一個數據屬性的set方法,都會先調用OnPropertyChange方法,其實就是爲了設置該字段的髒屬性,說明這個字段的數據曾經被修改過。生成Update語句的時候,只修改帶有髒屬性的字段。

實體類中,除了直接修改屬性外,還能夠經過索引器進行修改,兩種的區別就在於經過索引器修改屬性時,不影響髒數據設置。實際上,加載數據行到實體類中,使用的正是索引器,因此剛加載完成數據的狀況下髒數據是空的。

九、多數據庫支持

(MSSQL2000、MSSQL2005/200八、Oracle、MySQL、Access、SQLite)

與大多數ORM同樣,XCode經過接口的方式支持多種數據庫。在XCode中,爲每個數據庫實現了一個數據庫操做類,繼承自數據庫接口。數據訪問層DAL根據數據庫鏈接的配置識別是哪種數據庫,而後建立該數據庫操做類的實例,並經過操做接口來操做數據庫。

數據庫操做類以Access數據庫爲藍本,設計了一個基類,其它數據庫操做類僅須要繼承該類,重載功能點不一致的屬性和方法,大大減少了操做類的大小。

數據庫操做接口包含的功能有:查詢、執行、分頁、事務、獲取架構、DDL操做、數據庫版本等。實際上,各個數據庫的差別點均可以設計在操做接口中,而上層代碼根本不須要改動。

不少ORM都爲各個數據庫的差別大而苦惱,XCode開發模式則否則。咱們的原則是一切從簡,只使用SQL,不適用DbCommand和存儲過程。而所使用的SQL,基本上也是標準SQL,不會使用數據庫特性,而且都是單表操做。固然,這種方法也不是萬能的,不得已的時候,能夠在業務層判斷當前數據庫類型,根據不一樣數據庫編寫不一樣的SQL,但自XCode使用以來,還沒須要這樣作過。

十、獲取數據庫架構

(DAL.Tables)

在XCode中,數據庫架構主要包含XTable和XField類,顧名思義,它們表明着表和字段信息。數據訪問層DAL中有個成員屬性Tables能夠取得該數據庫鏈接的全部表信息,也就是一個XTable集合。同理,每個XTable中,都會有一個XField集合。

這樣設計,簡單明瞭,使用者能夠很容易的找到本身須要的東西。咱們的代碼生成器XCoder就是依賴於XCode來獲取數據庫架構的。有了這個功能,人人均可以寫本身的代碼生成器了!

十一、反向生成數據庫架構

(DatabaseSchema)

這是一個很另類的功能,極少有ORM提供。在開發和維護的過程當中,不免須要修改表結構,從新生成實體類(僅生成實體類數據文件部分)。在團隊開發的時候,若是不是共用數據庫,則還須要通知隊員作相應的修改。維護的時候,還須要到生產環境作更新,若是客戶不容許直接操做數據庫,那就更麻煩了。

在數據庫操做接口中,其中一個功能就是DDL操做,各個數據庫進行重載後,可使用DDL語句操做數據庫的結構。經常使用的功能有:建立表、修改字段屬性、添加字段、刪除字段等。

XCode除了會從數據庫生成數據庫架構外,還會從實體類生成一套數據庫架構,而後進行對比,發現存在差別後,直接修改或者寫日誌提醒(由設置決定)。修改開關沒打開時,僅僅寫日誌提醒,日誌中寫出了完整的用於修正數據庫架構的DDL語句,拿到數據庫中執行便可。

基於XCode開發的系統,在發佈的時候,歷來不帶數據庫,由於XCode會自動根據鏈接字符串建立數據庫、數據表和字段。即便開發使用的是A數據庫,發佈的時候修改數據庫鏈接字符串爲B數據庫,XCode將會按照B數據庫的規範來建立數據庫。若是系統發佈還須要附帶數據,那就不可能作到發佈時更換數據庫了,除非發佈多個數據庫的版本。

也許有人會說,不帶數據庫的話,初始化的數據怎麼辦?在XCode的開發理念中,建議在實體類增長靜態構造函數,用於檢測數據表數據,若是沒有數據時,是否須要建立一個默認數據,好比在管理員表建立一個用戶名和密碼都是admin的管理員。

十二、動態修改鏈接和表名

(Meta.ConnName,Meta.TableName)

數據量增大到必定程度時,不少企業的方案都是給數據表更名或者把該表遷移到別的數據庫中去,僅用於查詢統計。

在XCode中,生成實體類時,就指定了實體類所對應的表名,可是咱們並不須要爲多個具備相同表結構的表生成多個實體類,由於實體類能夠動態修改所指向的表名,使得操做的目標表發生改變。爲了不多線程環境所帶來的影響,該修改僅影響當前線程。

鏈接名的修改方式與表名相同。

1三、弱類型訪問

(IEntity,IEntityOperate)

有時候,咱們並不知道須要操做的是哪個實體類,只有在運行時才能肯定下來。經常使用的作法就是反射!

爲了不沒必要要的性能損耗,以及避免很不美觀的編碼設計方式,XCode提供了弱類型訪問的能力。能夠經過指定類型或者表名,反射找到實體類,建立一個IEntityOperate操做對象,從而完成對實體類的各類操做。

IEntityOperate所提供的方法跟實體類的靜態方法基本一致,在使用上不會遇到任何困難。IEntityOperate進行數據查詢時,返回的是IEntity集合,由於每個實體類,都實現了IEntity接口,足以完成基本的CURD操做。

1四、動態生成代碼

(CodeDOM,內存實體)

在弱類型訪問的支持下,有些簡單的數據庫操做並不必定須要生成實體類,XCode在找不到實體類時,將會根據表架構在內存中生成一個實體類,而後編譯使用。

動態生成的另外一目標是讓使用者經過調用一些方法來生成實體類代碼,而不是必定要經過XCoder來生成。

1五、擴展加載

(把查詢中的字段映射到擴展屬性)

XCode支持的是充血模型,從面向對象的角度上來說,這個對象的全部特色(屬性)和能力(方法)都應該在實體類上實現。除了基本的與數據庫字段對應的數據屬性外,還有一些跟別的實體對象關聯的屬性,咱們稱之爲擴展屬性。好比:Article.Board.Manager.UserName,能夠直接獲得一個帖子的版主的用戶名。

XCode不支持多表關聯查詢,可是它有擴展屬性,全部的多表關聯查詢,均可以經過擴展屬性來編碼實現。Article中的Board擴展屬性,是在使用的時候纔去加載的,加上Board可使用實體緩存,基本上沒有數據庫操做。Manager不能使用實體緩存,可是它做爲擴展屬性「掛」在Board上,間接「享受」了緩存。

還能夠編寫一個普通的屬性做爲擴展屬性,而後執行查詢的時候,經過selects參數把數據映射到該擴展屬性上。好比:增長一個Total的整型屬性,而後執行查詢Article.FindAll("BoardID=123",null,"Count(*) as Total",0,1),該查詢是取得欄目編號爲123的全部帖子數,而後把結果映射到Total屬性上,返回的記錄集只有一個實體對象,該實體對象的Total屬性就是所要查詢的帖子數,此時別的屬性沒有意義。

該功能通常用於查詢統計中。使用一個實體來表現數據,比數據集方便多了。

擴展屬性是充血模型所特有的東西,也是相對於貧血模型(含失血模型)的最大優點所在!

1六、泛型基類模型

(Entity)

XCode從v1.2起,就進入了第二代,關鍵點就在於泛型基類Entity的使用。

在第一代XCode中,由於充血模型,實體類上要附帶大量的方法,而當它們的返回類型是實體類或者實體類集合時,這些方法就必須實現於實體類的代碼中,其實是經過代碼生成器來生成。

在第二代XCode,引入了泛型基類技術,實體類經過泛型參數TEntity指定最終返回類型,編寫查詢方法的時候,返回類型使用泛型參數TEntity便可。因此,第二代實體類只有屬性和索引器,基本不須要生成查詢和操做的方法,由於它們都在泛型基類裏面實現了。

大多數狀況下,實體類指定的基類泛型參數就是它本身,由於它須要以它本身做爲返回類型。但XCode開發模式是面向對象的,包括實體類,也但願可以繼承,增長一些功能,該功能能夠經過改變泛型參數來實現。

1七、實體類的繼承與重載

(NewLife.CommonEntity)

經過改變泛型參數的具體類型,實現實體類的繼承和重載,是XCode進入第三代的標誌。它標誌着咱們能夠封裝一些基礎數據實體來供多個項目使用

通用實體組件NewLife.CommonEntity就是該功能的表明,封裝了地區、管理員、角色、菜單、受權等實體類。具體項目能夠直接使用它們,也能夠經過繼承與重載來實現擴展。

以封裝的地區表爲例,它在靜態構造函數中檢測數據錶行數,固然,在這以前XCode會自動檢測並建立地區表。若是地區表中沒有數據,則會調用一個方法進行數據初始化操做。地區表業務類代碼經過硬編碼方式,內置了全國幾千個地區的區域編碼和名稱。一旦國家修改區域劃分,只須要修改該類,全部使用該組件的項目都將使用上全新的區域數據。若是這些功能代碼都複製到每個使用的項目中去,將造成一個很是難以維護的情況。

 

XCode的十八般武藝就介紹到這,更多的功能須要你去發現!歡迎感興趣的朋友前來交流討論,QQ羣10193406

 

XCode就是爲了讓一切變得簡單!學習簡單、使用簡單、想法簡單……功能不簡單!

 

大石頭

新生命開發團隊

2010-09-24 4:18

做者: 大石頭 發表於 2010-09-25 09:21 原文連接

評論: 59 查看評論 發表評論

最新新聞:
· 是否該讓開發人員跟客戶直接交流?(2010-12-21 07:53)
· 亞馬遜副總裁跳槽Groupon任CFO(2010-12-21 07:50)
· Gmail語音服務將延長至2011年末(2010-12-21 07:49)
· AOL收購我的檔案網站About.me(2010-12-21 07:48)
· AT&T 19.25億美圓購入高通 700MHz 低頻頻譜(2010-12-21 07:42)

編輯推薦:Mono又更新了

網站導航:博客園首頁  個人園子  新聞  閃存  小組  博問  知識庫

相關文章
相關標籤/搜索