C++序列化存在多种方式,我这里使用的boost,推荐看一个简单的教程。
boost方法就是在类定义中添加一个友元类对象,并实现serialize()方法就可以让该类变为可序列化类。要使用boost序列化首先需要去boost官网下载相应的boost文件,然后需要include两个头文件,包括
#include#include
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位的库。
bjam stage --with-serialization link=static runtime-link=shared threading=multi debug release address-model=64
就可以生成64位的lib包。
自定义的可序列化类如下:
Person.h
#pragma once
#include //序列化需要的.h文件
#include //序列化需要的.h文件
#include
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
//定义为可序列化,友元类型,使得可以访问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串,需要的时候再反序列化出来。
#pragma once
#include "mysql_connection.h"
#include "mysql_driver.h"
#include "mysql_error.h"
#include
#include
#include
#include
#include
#include"Person.h"
#include
#include //序列化需要的头文件
#include
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 //stringstream流需要的头文件
#include
/*在构造函数中完成驱动的加载,连接的建立
*
*/
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
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;
}
运行后数据库截图如下:
输出截图如下: