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

来源:互联网 发布:小猪cms和有赞 编辑:程序博客网 时间:2024/05/22 03:25

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,passwordthis->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;//生成preparedStatementpres = 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();                   //执行查询//遍历reswhile (res->next()) {string pstr = res->getString("objvalue");             //取出该stringstd::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 0
原创粉丝点击