如何做到在虛擬數據庫和真實數據庫之間自由切換?【低調贈送:QQ高仿版GG 4.4 最新源碼】


      記得以前在公司上班時,有時候白天的活沒干完,我就會把工作帶回家晚上加班繼續做。但是,我們開發用的數據庫是部署在公司局網內部的一台服務器上的,在家里是肯定連不上這台機器的。在家里沒有數據庫,服務端就跑不起來,功能也就沒辦法調試。后來我們的解決方法就是使用虛擬數據庫。在公司上班時,就使用公司局網的真實數據庫;回到家,就使用內存中虛擬的數據庫,做一些基本的功能調試,絕對是足夠了。

      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。  

如果你覺得還不錯,請粉我,順便再頂一下啊 

 


免責聲明!

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



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