记得以前在公司上班时,有时候白天的活没干完,我就会把工作带回家晚上加班继续做。但是,我们开发用的数据库是部署在公司局网内部的一台服务器上的,在家里是肯定连不上这台机器的。在家里没有数据库,服务端就跑不起来,功能也就没办法调试。后来我们的解决方法就是使用虚拟数据库。在公司上班时,就使用公司局网的真实数据库;回到家,就使用内存中虚拟的数据库,做一些基本的功能调试,绝对是足够了。

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。

如果你觉得还不错,请粉我,顺便再顶一下啊

如何做到在虚拟数据库和真实数据库之间自由切换?【低调赠送:QQ高仿版GG 4.4 最新源码】的更多相关文章

  1. PHP批量替换MySql数据库中的数据内容(替换MySql数据库内容源码)

    PHP批量替换MySql数据库内容 UTF-8 1.0版 <?php //声明 //1.本源码开发意图:作者在使用一些CMS建站的时候发现很多CMS把网址写入到数据库了,如果换网址,那么就需要更 ...

  2. Sql Server数据库备份脚本以及如何在阿里云云数据库RDS还原数据库(代码源自阿里云)

    今天研究阿里云服务数据库的迁移,备份和还原的时候,在阿里云web后台发现了一个很好用的sql脚本,就默默地偷了过来,它可以支持全量备份,差异备份和日志备份,代码解释也都很清楚,我也尝试着跑了一下,性能 ...

  3. 虚拟dom和真实dom的转化和class解析的顺序

    昨天出去溜了一圈,被问到几个问题回来整理了一下,当被特意问到一看感觉就会的问题,千万要不要急于回答,先想想,因为这往往是一个被忽略的坑(例如class解析顺序)!!! 1.写出虚拟dom和真实dom之 ...

  4. 1.NetDh框架之数据库操作层--Dapper简单封装,可支持多库实例、多种数据库类型等(附源码和示例代码)

    1.NetDh框架开始的需求场景 需求场景: 1.之前公司有不同.net项目组,有的项目是用SqlServer做数据库,有的项目是用Oracle,后面也有可能会用到Mysql等,而且要考虑后续扩展成主 ...

  5. Godaddy虚拟主机新建mysql数据库 2019最新

    第一次用狗爹,完全摸不着路子. 网站本地已搭建,不知道数据库是在哪里上传. 百度搜索结果都是四五年前的旧内容,耽误时间. 还是问客服,Godaddy的客服确实不赖 godaddy虚拟主机如何新建数据库 ...

  6. MySQL之 视图,触发器,存储过程,函数,事物,数据库锁,数据库备份

    1.视图 视图: 是一个虚拟表,其内容由查询定义: 视图有如下特点;  1. 视图的列可以来自不同的表,是表的抽象和逻辑意义上建立的新关系.  2. 视图是由基本表(实表)产生的表(虚表).  3. ...

  7. 数据库MySQL之 视图、触发器、存储过程、函数、事务、数据库锁、数据库备份、事件

    数据库MySQL之 视图.触发器.存储过程.函数.事务.数据库锁.数据库备份.事件 浏览目录 视图 触发器 存储过程 函数 事务 数据库锁 数据库备份 事件 一.视图 1.视图概念 视图是一个虚拟表, ...

  8. MYSQL之视图、触发器、存储过程、函数、事物、数据库锁和数据库备份

    一.视图 -- view 视图:是一个虚报表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据. 视图有如下特点: 1.视图的列可以来自不同的表,是表的抽象和逻辑意义上建立的新关系 ...

  9. C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库

    C# DateTime的11种构造函数   别的也不多说没直接贴代码 using System; using System.Collections.Generic; using System.Glob ...

随机推荐

  1. sandy bridge

      SANDY BRIDGE SPANS GENERATIONS Intel Focuses on Graphics, Multimedia in New Processor Design By Li ...

  2. 用Python实现一个爬取XX大学电费通知的小脚本

    内容简要 1分析网站 2简单爬取 3进阶自定义爬取 4保存进数据库 学校基础设施太差,宿舍电量过低提醒虽然贴在楼下,但是作为低头一族,经常忘记看提醒导致宿舍酣战时突然黑屏,为了避免这种尴尬的场景以及强 ...

  3. php框架制做笔记

    在学习完基础之后,最好的提高方式是做一个自己的框架,因为框架会用到各个知识点,在制做过程中,复习,巩固,提高. 在框架中,因为是单入口,整个脚本运行时都存在的变量我们应该设为静态变量,这样它在每个地方 ...

  4. ss

    110000北京120000天津130000河北140000山西150000内蒙古210000辽宁220000吉林230000黑龙江310000上海320000江苏330000浙江340000安徽35 ...

  5. 常用邮件服务器名(POP3,SMTP地址)

    POP3服务器地址:pop3.sina.com.cn(端口:110)SMTP服务器地址:smtp.sina.com.cn(端口:25) sina.cn: POP3服务器地址:pop3.sina.com ...

  6. maven下读取资源文件的问题(转)

    原文链接:http://shenchao.me/2016/04/20/maven%E4%B8%8B%E8%AF%BB%E5%8F%96%E8%B5%84%E6%BA%90%E6%96%87%E4%BB ...

  7. 如何查看apache,php,mysql的编译参数

    查看nginx编译参数:/usr/local/nginx/sbin/nginx -V 查看apache编译参数:cat /usr/local/apache2/build/config.nice 查看m ...

  8. Session失效之 IE iframe cookie问题(p3p)

    项目中,在做门户系统时,使用了iframe嵌套展示各个子系统的页面,其中有个页面在ie8下,始终无法正常登陆. 后来项目经理分析,应该是iframe跨域导致,赶忙查看了连接地址,还真是一个跨域的页面. ...

  9. Subliem Text 3 的安装和使用

    前两天将Sublime Text3简单的看了看,发现是好经典的开发工具.... 1. sublime Text安装:www.sublimetext.com 此时的版本是: Build 3103 可用的 ...

  10. mysql在ubuntu下的安装

    如果是调用的apt-get 那么应该是sudo apt-get install mysql-server-core-5.6  mysql-server-5.6 mysql-common-5.6 mys ...