ASP.NET開源架構之HIPPO技術內幕(二)–Meta-Data驅動

來源:互聯網
上載者:User

二、Meta-Data驅動

    上一章從大的方向上介紹了一下HIPPO系統,從本章開始進入正題。

    為了更好的組織系統的結構,把所有的基礎資訊抽取出來儲存在資料庫中。這種方式從BroadVision中學習得來。

    為了實現這種資料的儲存,需要幾種不同類型的對象來儲存,如下:

對象

表名

含義

Schema

ZR_SCHEMA

模式

Content

ZR_CONTENT

內容

Table

ZR_TABLES

模式對應的表

Attribute

ZR_ATTRIBUTE

每個表的所有的欄位描述

    在上述表達中,Schema是整個Meta-Data結構的最底層,所有的資訊都要依附於它,那麼到底什麼是Schema呢,直譯就是“模式”,系統中所有的內容描述最後都要歸結為Schema的表達,如“新聞”、“使用者”、“產品”等一系列內容,也就是可以理解為同類的內容屬於一個Schema。

    Content就是內容的意思,根據CMS來看,它應該是比較重要的一個層面,沒錯,在本系統中,Content實際上是對Schema的擴充,他擁有更多的屬性,並且Schema和Content必須是一一對應的,如果有可能,可以理解為這兩個屬於同一部分,在實際應用中,我也做了一些觸發器,當修改Content的時候,會同時去修改相關聯的Schema,那麼一定有人會問,那為什麼還要分成兩部分來儲存呢,呵,說來話長,本來想完全學習BroadVision的方式,但是最後做了簡化,所以有了今天的樣子。

    Table理解起來就更容易了,它完全沒有上面兩個對象的抽象與神秘,就是用來說明上面的內容都是用哪些表來儲存資料,本來嘛,在關係型資料庫中,說來說去,不管表現層如何,最後必須把資料存放區在具體的表中。Shema與Table是一對多的關係,即同一個內容可以用多個表來儲存,舉個例子,“使用者”這個模式,分成幾個主要的表,一個是ZR_USER,裡面儲存著會員ID,會員登入號及密碼等幾個最基本的欄位,ZR_USER_PROFILE這個表,儲存著使用者的擴充屬性,如會員姓名,生日,身份證等。用的時候,把兩個表加起來可以相當於一張表來使用。這種資料存放區方式與把使用者的所有欄位均寫在一個表中是兩種完全不同的設計思想,其實本質上並沒有誰好誰壞的區別,最主要的區別是在資料量很大的時候,我這種設計方式對資料庫的壓力會小一些,因為在登入的時候,只需要檢查幾個有限的欄位,即便進行全表描述,也會佔用更小的IO操作。還有第三種表,就是“子表”,我來給子表舉個例子,一個會員可以擁有多個Email地址,如果把這些欄位全放在一張表中,那就要預留多個欄位,所以把它單獨建一張表,然後用一個外鍵和使用者表對應起來,就可以表達使用者與EMAIL的一對多的關係,在前端展示的時候,會為這種一對多的子表有一個專門的表現方式。

    Attribute更容易理解了,其實就是資料庫中的欄位,也就是說上面的Table所對應的欄位的描述都存放在這個表中。為什麼不叫Column呢,因為叫Attribute更具有對象的感覺,感覺能超越資料庫似的,哈,其實沒有區別。

    其實在任何的資料庫中,都可以找到一個系統資料表,裡面儲存著每個TABLE所對應的欄位描述,為什麼我們還要專門建立一個自己的表來重複儲存呢?很顯示,系統儲存的資訊完全是DB自有的資訊,不能擴充,而且每個資料庫的儲存方式也不同,所以把它單獨提取出來。

    在系統中,開發了四個類來實現對以上四個表的描述,另外,還專門建了兩個管理器的類對上述幾個類進行管理,如下:

        SchemaManager

        ContentManager

    使用這兩個管理器可以建立新的Schema或修改已經存在的Content等。總之,這一切工作的想法就是盡量減少使用者與資料庫的直接打交道,把所有的操作全部封裝起來。用起來更有物件導向的感覺。

    這裡面有一個問題值得談一下,使用對象方式的時候,對象的屬性是在寫程式的時候固定的,比如會員的身高、體重等,這些固化的屬性並不會隨著定製化而改變,可是資料庫中的表完全有可能在定製過程中變得千差萬別,那麼用對象描述的時候怎麼樣保證他們能順利的對應起來呢,我的做法是找幾個固定的欄位做成類的屬性,如登入名稱,密碼等,而姓名,身份證等資訊,在User類中並找不到一個真正對應的屬性,而是把所有這些屬性放在一個大的Hashtable中,形成一個複合的屬性,取個名字叫做 Properties,所以在使用的時候可以按如下方式引用

    user.UserAlias 是使用者的登入名稱

    user.Properties[“NAME”] 就是會員的姓名

    由上可以看出,不管對屬性做了多少擴充,都可以用這種方式來很好的呈現了。

    關於使用者的密碼儲存及使用,後面會有專門的章節來討論。

    再來舉個例子,如何取出所有的新聞:

    假如新聞的Content的名字是EDITORIAL,則程式可以這樣寫:

        ContentManager contentManager = new ContentManager(“EDITORIAL”);

        DataTable table = contentManager.GetContent();

    只要上述兩句簡單的描述就可以把所有的新聞取出來放入一個DataTable中備用,後期可以利用它直接填入DataGrid中。

    在很多情況下,並不需要取出所有的新聞,這時就要做一個條件過濾,或取出前10條,或按某個欄位排序等,針對所有這些功能,都已經對contentManager.GetContent()函數進行了多種重載,只要加上適當的參數即可,由於篇幅有限,不能一一說明。

    聽到現在,可能一直都是比較抽象的,也不知我到底要做什麼,到底在幹什麼,但是Meta-Data這部分是系統的核心思想,理解這部分內容,即便不看後面的章節,也會對您以後的設計有很大的協助。從下一部分開始,會進行部分關鍵代碼的描述。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.