記得以前在公司上班時,有時候白天的活沒幹完,我就會把工作帶回家晚上加班繼續做。但是,我們開發用的資料庫是部署在公司局網內部的一臺伺服器上的,在家裡是肯定連不上這臺機器的。在家裡沒有資料庫,服務端就跑不起來,功能也就沒辦法除錯。後來我們的解決方法就是使用虛擬資料庫。在公司上班時,就使用公司局網的真實資料庫;回到家,就使用記憶體中虛擬的資料庫,做一些基本的功能除錯,絕對是足夠了。
GG之前的版本一直只支援虛擬資料庫,因為部署、演示都非常方便。後來有很多朋友要求增加對真實資料庫的支援,那麼這次GG的最新版本V4.4 就滿足了大家的這一需求,真實資料庫使用SqlServer(2000/2005/2008),並使用一個配置就可以在真實/虛擬資料庫之間自由切換。本文就將詳細介紹我們是如何實現在虛擬資料庫和真實資料庫之間自由切換這一功能的。
想要直接下載體驗的朋友請點選:“下載中心”
一. 什麼是虛擬資料庫?
剛baidu了一下,似乎沒有“虛擬資料庫”這個專業術語。那麼我就結合類似上面的使用場景,按照自己的理解來簡單解釋一下,虛擬資料庫有以下幾個要點:
(1)“虛擬”是和“真實”相對的。它不是一個真實的資料庫,而是一個資料庫的模擬。
(2)只在軟體執行的過程中存在。比如,當服務端啟動時,會在記憶體中構建這個虛擬資料庫。
(3)只存在於記憶體中,沒有持久化機制。比如,在服務端執行過程中,會對虛擬資料庫進行CRUD操作,但是當服務端重啟後,這些修改就都會丟失,虛擬資料庫又會恢復到它的初始狀態。
(4)不需要任何部署。這是虛擬資料庫最方便的地方和最大的好處了。我們都知道有時僅僅為了給客戶演示一個簡單的小功能,就需要安裝一個龐大的SqlServer或Oralce,是多麼痛苦的一件事!
二. 虛擬資料庫如何實現?
我們經常用Dictionary<,>模擬一個虛擬資料庫中的表,Dictionary的key就模擬表的主鍵,value就模擬一條記錄。比如,GG中的使用者表GGUser,在虛擬資料庫中就可以這樣模擬:
//模擬GGUser表 private Dictionary<string, GGUser> userTable = new Dictionary<string, GGUser>(); //模擬插入一個GGUser public void InsertUser(GGUser user) { lock (this.userTable) { this.userTable.Add(user.ID, user); } }
類似上面的程式碼,我們可以很快地寫出與GGUser表相關的CRUD操作。同理,也可以模擬GGGroup(GG群)表、ChatMessageRecord(聊天記錄)表等等。
我們把所有對虛擬表的操作全封裝在一個類VirtualDB中,於是,我們就可以程VirtualDB就是虛擬資料庫的抽象了。
在VirtualDB的建構函式中,我們可以為虛擬表新增一些測試資料,這樣,服務端啟動後,就有一些基礎資料提供給除錯、測試、或Demo演示使用了。
三. 如何實現在虛擬資料庫和真實資料庫之間切換?
1. 里氏替換原則
我們首先回憶一下,經典OO設計原則中的一個:里氏替換原則。這個原則是這樣說的:所有引用基類的地方必須能夠透明地使用其子類的物件。
似乎有點拗口,下面就結合GG中的實現解釋一下:
(1)GG中用於表示虛擬資料庫的類是VirtualDB類,用於表示真實資料庫的類是RealDB類。
(2)VirtualDB類和RealDB類都從介面IDBPersister介面繼承。
(3)但是,GG服務端程式中凡是涉及到資料庫訪問操作的地方,既不使用VirtualDB、也不使用RealDB,而是使用IDBPersister。
這樣,我們就只需要在程式啟動的時候,指定將VirtualDB例項或RealDB例項指派給IDBPersister引用,就可以讓整個服務端統一地訪問虛擬資料庫或是真實資料庫了。
結合這個例項,我們把里氏替換原則放到這個場景中,其意思就是:在程式中不要依賴具體的實現類(VirtualDB和RealDB),而是依賴於它們的共同介面(IDBPersister)。這樣,替換就很方便了。
2. 使用配置檔案
如果打算將使用VirtualDB還是使用RealDB的決定權交給使用者,那麼只需要在配置檔案中增加一個配置項即可。比如:
<!--使用記憶體虛擬資料庫--> <add key="UseVirtualDB" value="false"/> <!--資料庫名稱--> <add key="DBName" value="GG2014"/> <!--資料庫IP--> <add key="DBIP" value="127.0.0.1"/> <!--資料庫sa的密碼--> <add key="SaPwd" value="123qwe"/>
上述的配置,還包含了資料庫的相關資訊。如果要使用虛擬的資料庫,只需要將UseVirtualDB項配置為true即可。
在服務端啟動的時候,讀取配置,然後決定是否使用虛擬資料庫。
IDBPersister persister; if (bool.Parse(ConfigurationManager.AppSettings["UseVirtualDB"])) { persister = new VirtualDB(); } else { persister = new RealDB( ConfigurationManager.AppSettings["DBName"] ,ConfigurationManager.AppSettings["DBIP"], ConfigurationManager.AppSettings["SaPwd"]); } GlobalCache globalCache = new GlobalCache(persister);
四.GG V4.4 原始碼
下載最新版本,請轉到這裡。
GG是可在廣域網部署執行的QQ高仿版,2013.8.7釋出V1.0版本,至今最新是4.4版本,關於GG更詳細的介紹,可以檢視 可在廣域網部署執行的QQ高仿版 -- GG2014總覽。
在GG的最新版本中使用了上述方案以支援在真實資料庫和虛擬資料庫之間相互切換。
________________________________________________________________________
歡迎和我探討關於 GG 和 GGMeeting 的一切,我的QQ:2027224508,多多交流!
大家有什麼問題和建議,可以留言,也可以傳送email到我郵箱:2027224508@qq.com。
如果你覺得還不錯,請粉我,順便再頂一下啊