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

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. makfile

    1. Makefile 简介 Makefile 是和 make 命令一起配合使用的. 很多大型项目的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项目中各种库和代码之 ...

  2. BingMap

    Application name Key details BngMapTest Key:25nTPiuDe0kxITMR1ymE~j5IlskEImiwGsGmAnsCftQ~Ap0HigfJujLq ...

  3. 解决PKIX(PKIX path building failed) 问题 unable to find valid certification path to requested target

    最近在写java的一个服务,需要给远程服务器发送post请求,认证方式为Basic Authentication,在请求过程中出现了 PKIX path building failed: sun.se ...

  4. Spark简介

    Spark是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用并行框架,Spark,拥有Hadoop MapReduce所具有的优点:但不同于MapReduce的是 ...

  5. OD使用教程10

       首先载入程序,然后Ctrl+N打开输入输出表 然后直接输入要找到函数,找到之后下断点,右键-在每个参考上设置断点 然后运行程序来到第一个断点处 然后f8走,开始找注册码没找到就换一个函数,然后看 ...

  6. hdoj 1002 A+B(2)

    Problem Description I have a very simple problem for you. Given two integers A and B, your job is to ...

  7. XAMARIN +VS2015 ANDROID 开发禁止屏幕自动转动 Portrait,Nosensor

    网上有很多java的写法,但是放在C#中都无法使用,其实有时候还是安下心来认真的去看官网文档比在百度或者google来的快的多 this.RequestedOrientation = Android. ...

  8. gitlab安装过程总结

    gitlab总算搭建好了,今天下午完成了第一个工程的导入. 梳理下搭建的过程: 1.下载bitnami的一键安装包,并安装 注意设置权限为777,以免出现某文件写入错误的问题 2.配置邮件服务 分别修 ...

  9. linux环境下安装mongodb

    最近有用到mongodb,顺便找到了以前的指南,顺便写一篇随笔,以后或许有用到的地方. 第一步:下载mongodb的linux版本,mongodb-linux-x86_64-3.2.4.tgz(去官网 ...

  10. json_encode中文unicode的问题

    近期做微信卡券开发遇到一个问题,创建卡券post数据给服务器时返回data format error, do NOT use json unicode encode (/uxxxx/uxxxx), p ...