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

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;
}

运行后数据库截图如下:


输出截图如下:


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值