一、MongoDB数据库简介
简介
特点
MongoDB官方下载地址:http://www.mongodb.org
二、MongoDB win32下的C++驱动 编译以及mongodb里面用到的boost_1_35_0库的编译(这种编译成mongoclient.lib使用的方法最好,不过本人没有折腾出来,以后再慢慢研究吧)
对于MongoDb的优势和一些规则就不细说了,详见MongoDB实战中文版.pdf
MongoDB权威指南.pdf
在http://www.mongodb.org下载了最新版的,但是发现没有win32下的C++驱动,不得已,继续查找资料。
终于找到了一个1.2.1的windows32版本:
http://downloads.mongodb.org/win32/mongodb-win32-i386-1.2.1.zip
其中含有
执行该文件即可启动mongodb服务程序。
解压文件内还包含了c++的头文件和库文件。
将他们放到以下目录:
D:\mongodb\include
D:\mongodb\lib
所以打算利用它们来写mongodb客户程序。
但是
首先需要有boost,因为mongodb-win32-i386-1.2.1.zip里提供的mongodb库文件
D:\mongodb\1.2.1\mongodb-win32-i386-1.2.1\lib\mongoclient.lib
是用vs2008 + boost_1_35_0编译出来的,懒得重新编译mongodb,因此也对应的使用vs2008 + boost_1_35_0编译环境即可使用这个mongoclient.lib,boost_1_35_0从boost官网下载即可。
编译boost分两步:
1.执行D:\1.2.1\boost\boost_1_35_0\tools\jam\build_dist.bat
2.将第一步生成的bjam.exe拷贝到D:\boost\boost_1_35_0,然后执行:
cd D:\boost\boost_1_35_0
bjam.exe link=static threading=multi variant=release runtime-link=static --without-python --toolset=msvc-9.0
其中各参数的含义如下:
--build-dir=<builddir> 编译的临时文件会放在builddir里(编译完就可以把它删除了)
--stagedir=<stagedir> 存放编译后库文件的路径,默认是stage
--build-type=complete 编译所有版本,不然只会编译一小部分版本
(相当于variant=release,threading=multi;link=shared|static;runtime-link=shared)
variant=debug|release 决定编译什么版本(Debug orRelease)
link=static|shared 决定使用静态库还是动态库
threading=single|multi 决定使用单线程还是多线程库
runtime-link=static|shared 决定是静态还是动态链接C/C++标准库
--with-<library> 只编译指定的库,如输入--with-regex就只编译regex库了
--show-libraries 显示需要编译的库名称
完成后即会生成很多lib库,比如libboost_program_options-vc90-mt-s-1_35.lib,把这些lib库文件(搜索lib关键字)全部拷贝到D:\mongodb\uselib目录(uselib目录是我自己建立的)。
为了重复利用,以及方便以后可能delphi等其他编译器的运用,决定将一些常用功能编译成dll。
首先利用vs2008建立win32工程DLL,并做下设置:
1.工具-->选项-->项目和解决方案-->VC++目录
加上对应的包含文件:
D:\boost\boost_1_35_0
D:\mongodb\include\mongo
加上对应的库文件:
D:\mongodb\uselib
D:\mongodb\lib
(注:本来用的是1.2.1版本,但是我的系统中发生了点问题,后来用了1.8.1版本,但是驱动的头文件和库文件都没变)
2.项目-->属性(Alt+F7)-->配置属性-->C/C++-->代码生成-->运行时库选为多线程(/MT),即是静态的,不要用DLL。(对应boost库中”-mt-s-“名称)。
3. 项目-->属性(Alt+F7)-->配置管理器-->活动方案为release。(如果是debug会报错找不到-mt-sgd-)。
三、直接mongodb源码的使用(不编译成mongoclient.lib的方法)
备注:
因为只使用到插入功能,也不会太增加程序本身的体积,主要是几个boost库的lib链接进来增加了点体积。
你的工程里应做如下配置:
1、要引入 Ws2_32.lib库
2、指定包含头文件目录的路径 ..\..\..\Include\Common\mongodb\src;..\..\..\Include\Common\boost_1_35_0
3、指定包含编译后的boost库的路径 ..\..\..\Lib\boost_lib (debug版就用debug版,release版就用release版的boost库)
4、工程的“Solution”中的“Source Files” 将mongodb中的mongo_client_lib.cpp文件添加进来即可;(建议:mongodb源码版本尽量跟mongodb服务器版本一致,本人下载的是2.2.7版本的Mongodb源码)
在工程中包含 #include "mongo\client\dbclient.h"
写mongodb客户端时,若只是简单的增删改查操作,mongodb不一定需要用到编译出来的所有boost 的lib库,本人只用到插入操作,编译过程中只用到下面一些库(这样避免用源代码导致我们写的客户端过大):
libboost_date_time-vc90-mt-gd-1_35.lib
libboost_filesystem-vc90-mt-gd-1_35.lib
libboost_program_options-vc90-mt-gd-1_35.lib
libboost_system-vc90-mt-gd-1_35.lib
libboost_thread-vc90-mt-gd-1_35.lib
由于我开发的DLL库要是支持MFC extension DLL,必须为动态发布,这时工程里肯定要包含MFC的运行库,在工程里这样配置,alt+F7->配置属性->C/C++->Code Generation->Runtime Library 属性一般在发布的时候要进行静态发布,因为目前的操作系统正在换代,平台比较多,所以debug:Multi-threaded Debug(MD)
我在提供Release版本时,使用到的是libboost_thread-vc90-mt-1_35.lib 等boost库(按如下几个参数编译 bjam.exe link=static threading=multi variant=release --without-python --toolset=msvc-9.0 )
不知道为什么,Mongodb官网下载的源码在自己工程中编译总会有一些看似很正常的使用的错误,不过没关系,既然是开源的,我只需要将对应的错误剔除掉就行(建议尽量不要去改源码去剔除错误,除非你确定你的改动对源码的上下文没什么影响就去改吧)
四、往Mongodb数据库中插入C++对象,如类中的属性,STL对象map,set等
mongodb数据库中的表结构都是键值对的形式,这里拿个例子来讲,我们要插入一个map,只需要将该map 生成一个BSON二进制JSON对象,在往mongodb中插入一个BSON对象,相当于插入一条记录。
mongo::BSONObj bsonObjMap; mongo::BSONObjBuilder bsonObjBuilder; string strKey = "", strValue = ""; COLLECTDATA_MAP::iterator iBegin = pDeviceInfOut->m_mapCollectData.begin(); COLLECTDATA_MAP::iterator iEnd = pDeviceInfOut->m_mapCollectData.end(); while(iBegin != iEnd) { strKey = iBegin->first; strValue = iBegin->second; bsonObjBuilder.append(strKey, strValue); iBegin++; } bsonObjMap = bsonObjBuilder.obj(); mongo::BSONObjBuilder bsonObjBuilderRecorder; bsonObjBuilderRecorder.append("gatewayID", strGatewayID).append("deviceID", pDeviceInfOut->m_strDeviceID).append("collectTime", pDeviceInfOut->m_strCollectTime); bsonObjBuilderRecorder.append("data", bsonObjMap); string strTable = m_strDBName; strTable += "."; strTable += strTableName.c_str(); m_conn.insert(strTable, bsonObjBuilderRecorder.obj());