您的位置:首页 > 编程语言 > C语言/C++

C++中序列化对象并存储到mysql

2017-04-26 15:31 357 查看

1.序列化

C++序列化存在多种方式,我这里使用的boost,推荐看一个简单的教程
boost方法就是在类定义中添加一个友元类对象,并实现serialize()方法就可以让该类变为可序列化类。要使用boost序列化首先需要去boost官网下载相应的boost文件,然后需要include两个头文件,包括
#include <boost\archive\text_oarchive.hpp>  
#include <boost\archive\text_iarchive.hpp> 
要使用这两个头文件需要在项目中引入boost,并引入serialize.lib包,具体做法如下:
点击项目->属性->C/C++->常规,在附加包含目录中选择下载的boost解压路径,完成boost引入
如下图所示:



然后是引入serialize.lib包,具体做法如下点击项目->属性->连接器->常规,在附加包含
目录中选中serialize.lib包路径,一般在boost解压路径的stage/lib目录下。具体如图所示:



注意:serialize.lib文件是需要手动生成的,具体步骤为:
1.进入cmd,进入到boost所在文件夹,然后执行bootstrap.bat文件,会生成b2.exe和bjam.exe
两个可执行文件。
2.然后执行
bjam stage --with-serialization link=static runtime-link=shared threading=multi debug release
就会生成stage/lib文件夹和相应的lib文件。
参数定义如下:
stage 仅创建和安装库文件(不创建头文件),可以用 –stagedir= 选项指定库的安装位置,默认安装在当前目录下的stage文件夹内。
–with- 创建和安装指定的库,如果使用了这个选项,则仅仅指定的库被创建,其它库不被创建,本例中选的是serialization包。
如果不指定这个选项,默认创建所有需要编译安装的库。
link=static指定生成静态regex库
threading=multi指定生成多线程库
runtime-link=shared指定动态链接C和C++ 运行库
这样生成的是32位的库。

如果要生成64位的,则需要进入VS自带的64位命令提示工具。也是先生成b2.exe和bjam.exe文件,
然后再执行一下语句:
bjam stage --with-serialization link=static runtime-link=shared threading=multi debug release address-model=64
就可以生成64位的lib包。
自定义的可序列化类如下:
Person.h
#pragma once
#include <boost\archive\text_oarchive.hpp> //序列化需要的.h文件
#include <boost\archive\text_iarchive.hpp> //序列化需要的.h文件
#include<iostream>
using namespace std;
class Person
{
public:
Person();
~Person();

int getAge() const;
void setAge(int age);

string getName() const;
void setName(string name);

void toString();

private:
string name; //名字
int age; //年龄
template <typename Archive>
//定义为可序列化,友元类型,使得可以访问private变量
friend void serialize(Archive &ar, Person &p, const unsigned int version) {
ar &p.age; //定义可序列化反序列化变量
ar &p.name; //定义可序列反序列化变量
}
};

Person.cpp
#include "Person.h"

Person::Person()
{
}

Person::~Person()
{
}

int Person::getAge() const {
return age;
}
void Person::setAge(int age) {
this->age = age;
}

string Person::getName() const{
return this->name;
}

void Person::setName(string name) {
this->name = name;
}

void Person::toString() {
cout << "name:" << this->name << ",age" << this->age << endl;
}上面的.h文件定义中,实现了一个友元函数,实现了serialize函数,表示可序列化。可以将类的实例对象序列化为string串,然后用数据库存储响应的string串,需要的时候再反序列化出来。

(二)连接mysql并存储

C++连接mysql有两种办法,一种是用mysql自带的mysql.h连接法,另外一种是去mysql官网下载C++ Connector文件,里面封装了一套类似于java的连接和操作mysql的类和方法。C++ Connector连接mysql的方法就是先实例化驱动类(加载驱动),然后写好url,用户名和密码,再用驱动建立好连接,就能够用statement或者preparedStatement来操作数据库,和java里很像。要使用C++ Connector首先去mysql官网下载,然后引入里面的include文件夹和lib文件夹。具体做法如下:右键项目->属性->C/C++->常规,往附加包含目录中添加c++ Connector中include文件夹路径,如图所示:


然后就是引入c++ connector中的lib文件夹,具体做法是右键项目->属性->链接器->常规,然后点击附加库目录中选择c++ connector中lib文件夹目录,如图所示:


这样就完成了相应的库的引入。然后还需要将mysqlcppconn.dll(在c++ connector的lib中)添加到项目的debug或者release目录中,具体看你是debug模式还是release模式。然后是c++连接数据库并实现一些操作的代码:DBHelper.h
#pragma once
#include "mysql_connection.h"
#include "mysql_driver.h"
#include "mysql_error.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>

#include"Person.h"
#include<iostream>

#include <boost\archive\text_oarchive.hpp>               //序列化需要的头文件
#include <boost\archive\text_iarchive.hpp>
using namespace std;

class DBHelper
{
public:
DBHelper();
~DBHelper();

void saveObj(Person p);
void readObj();
private:
sql::mysql::MySQL_Driver *driver = NULL;             //定义驱动
sql::Connection *con = NULL;                         //定义链接
};
DBHelper.cpp
#include "DBHelper.h"

#include <iostream>                                                   //stringstream流需要的头文件
#include <sstream>

/*在构造函数中完成驱动的加载,连接的建立
*
*/
DBHelper::DBHelper()
{
this->driver = sql::mysql::get_driver_instance();             //得到驱动实例
if (this->driver == NULL) {
cout << "驱动记载出错" << endl;
}
else {
cout << "驱动加载成功!!!" << endl;

//参数依次为url,user,password
this->con = driver->connect("tcp://localhost:3306", "root", "201624560");
if (this->con == NULL) {
cout << "数据库连接失败" << endl;
}
else {
cout << "数据库连接成功!!!" << endl;
}
}

}

DBHelper::~DBHelper()
{
con->close();
delete con;
}

/*
*实现插入对象到数据库中
*params:
*	p:待插入的Person对象
*/
void DBHelper::saveObj(Person p) {
std::stringstream ss;
//使用stringstream流作为参数,这样可以将序列化结果写入到流中
boost::archive::text_oarchive oa(ss);
oa << p;                                                      //将对象p写入
string pstr = ss.str();                                       //将流数据转化为string数据

sql::Statement * stmt = NULL;
stmt = con->createStatement();
if (stmt == NULL)
{
cout << "stmt is null" << endl;
return;
}
stmt->execute("USE liuwei");                                  //使用表所在的数据库

sql::PreparedStatement *pres = NULL;
//生成preparedStatement
pres = con->prepareStatement("insert into cobjtest(objvalue) values(?)");
pres->setString(1,pstr);                                      //前面1对应第一个问号,后面是string值
pres->executeUpdate();                                        //执行插入

stmt->close();
if (pres != NULL)
pres->close();
}

/*
*从数据库中读出对象,并且将对象输出
*
*/
void DBHelper::readObj() {
sql::Statement * stmt = NULL;
stmt = con->createStatement();
if (stmt == NULL)
{
cout << "stmt is null" << endl;
return;
}
stmt->execute("USE liuwei");                                  //使用表所在的数据库

sql::PreparedStatement *pres = NULL;
pres = con->prepareStatement("select objvalue from cobjtest");//生成查询
sql::ResultSet *res = pres->executeQuery();                   //执行查询

//遍历res
while (res->next()) {
string pstr = res->getString("objvalue");             //取出该string

std::stringstream newss;
newss << pstr;                                        //将字符串读入流中
boost::archive::text_iarchive ia(newss);              //以stringstream流对象为参数构造序列化流
Person p;
ia >> p;                                              //读出对象
p.toString();
}

stmt->close();
if (pres != NULL)
pres->close();
}
数据库名为liuwei,表名为cobjtest,表结构截图如下:


测试用的主函数如下:
#include"Person.h"
#include"DBHelper.h"
#include<iostream>
using namespace std;
int main() {
Person p1;
p1.setAge(24);
p1.setName("liubaoan");

Person p2;
p2.setAge(23);
p2.setName("liuwei");

DBHelper db;
db.saveObj(p1);
db.saveObj(p2);

db.readObj();

return 0;
}

运行后数据库截图如下:



输出截图如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐