我是C++,MySQL和Boost的新手...

我正在尝试使用BLOB将c++对象存储在mySQL数据库中。

我正在使用boost::archive对我的对象进行序列化和反序列化。

存储Blob似乎可以正常工作,但是当我尝试反序列化结果Blob时,程序崩溃。
我真的会给您一个关于如何使它工作的提示。

我的目标是存储更复杂的对象,但是现在,我正在尝试一个非常简单的类:

class user
{
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & id_;
        ar & name_;
        ar & age_;
    }
    int id_;
    std::string name_;
    int age_;

public:
    user () {};
    user (int id,std::string name, int age)
    {
        id_ = id;
        name_ = name;
        age_ = age;

    };
    int id(){
        return id_;
    };
    std::string name(){
        return name_;
    };
    int age(){
        return age_;
    };
};

这是主要功能:
int main(){
    // a test object
    user u1(1,"myName",20);

    // serialization
    std::stringstream str;
    {
        boost::archive::binary_oarchive oa(str);
        oa << u1;
    }

    //mysql
    sql::Driver *driver;
    sql::Connection *con;
    sql::Statement *stmt;
    sql::ResultSet *sqlRes;
    sql::PreparedStatement *prep_stmt;
    try {
        /* Create a connection */
        driver = get_driver_instance();
        con = driver->  connect("tcp://127.0.0.1:3306", "root", "mypass");
        stmt = con->createStatement();

        //test database with a table named users containing only one column, a BLOB(10000)
        stmt->execute("use test");

        prep_stmt = con -> prepareStatement ("insert into users(obj) VALUES(?)");
        prep_stmt->setBlob(1,&str);
        prep_stmt->execute();
    }
    catch (sql::SQLException &e) {
        //some stuff...
        (...)
    }

    //Reading the only element in the table
    sqlRes = stmt->executeQuery("select * from users");
    sqlRes->next();
    std::istream *blobdata = sqlRes->getBlob(1);

    //trying to deserialize the blob...
    user newUser;
    {
        boost::archive::binary_iarchive ia(*blobdata); //crashes at this line
        ia >> newUser;
    }

    //If it worked, we should see our original user data...
    cout << "id = "<< newUser.id() <<endl;
    cout << "name = "<< newUser.name() <<endl;
    cout << "aeg = "<< newUser.age() <<endl;

    return 0;
}

我知道我可能做错了非常严重的事,但我无法弄清楚!

请帮助我,谢谢。

编辑1:

getBlob()返回null_ptr,但我不知道为什么。

如果我这样做是为了找回对象:
std::stringstream ss;
ss << sqlRes->getString(1);

user newUser;
{
    boost::archive::binary_iarchive ia(ss);
    ia >> newUser;
}

它可以工作,并且对象可以正确恢复...虽然不确定它是否可以用于更复杂的对象。

编辑2:

事实证明,由于@sehe(感谢您的帮助)尝试了我所做的相同的事情,因此对我而言他的工作对我而言是错误的。因此,上面的原始代码实际上是正确的。

最佳答案

我刚刚花时间完全重播了该示例。

这个对我有用。我创建一个这样的数据库:

 create database test;
 use test;
 create table users (obj mediumblob NULL);

我编译以下程序(适当替换数据库用户/名称):
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <cppconn/driver.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/exception.h>
#include <sstream>
#include <iostream>

class user
{
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & id_;
        ar & name_;
        ar & age_;
    }
    int id_;
    std::string name_;
    int age_;

public:
    user () {};
    user (int id,std::string name, int age)
    {
        id_ = id;
        name_ = name;
        age_ = age;

    };
    int id(){
        return id_;
    };
    std::string name(){
        return name_;
    };
    int age(){
        return age_;
    };
};

int main(){
    // a test object
    user u1(1,"myName",20);

    // serialization
    std::stringstream str;
    {
        boost::archive::binary_oarchive oa(str);
        oa << u1;
    }

    //mysql
    sql::Driver *driver;
    sql::Connection *con;
    sql::Statement *stmt;
    sql::ResultSet *sqlRes;
    sql::PreparedStatement *prep_stmt;
    try {
        /* Create a connection */
        driver = get_driver_instance();
        con = driver->  connect("tcp://127.0.0.1:3306", "root", "*********");
        stmt = con->createStatement();

        //test database with a table named users containing only one column, a BLOB(10000)
        stmt->execute("use test");

        prep_stmt = con -> prepareStatement ("insert into users(obj) VALUES(?)");
        prep_stmt->setBlob(1,&str);
        prep_stmt->execute();
    }
    catch (sql::SQLException &e) {
        //some stuff...
        exit(255);
    }

    //Reading the only element in the table
    sqlRes = stmt->executeQuery("select * from users");
    sqlRes->next();
    std::istream *blobdata = sqlRes->getBlob(1);

    //trying to deserialize the blob...
    user newUser;
    {
        boost::archive::binary_iarchive ia(*blobdata); //crashes at this line
        ia >> newUser;
    }

    //If it worked, we should see our original user data...
    std::cout << "id   = " << newUser.id()   << std::endl;
    std::cout << "name = " << newUser.name() << std::endl;
    std::cout << "aeg  = " << newUser.age()  << std::endl;

    return 0;
}

注意这会泄漏资源。您将要解决该问题。

运行时,它会打印
sehe@desktop:/tmp$ ./test
id   = 1
name = myName
aeg  = 20

和mysql显示:
mysql> select * from users;
+---------------------------------------------------------------------+
| obj                                                                 |
+---------------------------------------------------------------------+
|        serialization::archive
                                                   myName    |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)

07-28 00:46
查看更多