在 C++ 中序列化对象并作为 blob 类型存储在 mysql 中
我正在使用 mysql/C++ 连接器连接到 mysql 数据库。我有一些复杂的数据结构,所以我需要序列化它们并保存在数据库中。
我尝试了类似以下的内容。
vector<int> vectorTest(10,100);
istream *blob = NULL;
ostringstream os;
int size_data = sizeof(vector<int>);
blob = new istringstream((char*)&vectorTest, istringstream::in | istringstream::binary);
string qry = "INSERT INTO vector(id,object) VALUES (?,?)";
prep_stmt = con->prepareStatement(qry);
prep_stmt->setInt(1,1);
prep_stmt->setBlob(2,blob);
prep_stmt->execute();
我只是在这里尝试了一个小例子。然而,矢量对象没有被保存。
或者我可以使用以下方法。
ostringstream os;
int size_data = sizeof(vector<int>);
os.write((char*)&vectorTest, size_data);
但是我不知道如何将输出流重定向到输入流,因为 setBlob() 方法需要 istream 作为输入参数。
我可以知道如何让这些示例发挥作用吗?如果我的方法不正确,任何人都可以提供代码示例或改进给定的代码段吗?非常感谢您的立即回复。
谢谢
I am using mysql/C++ connector to connect to a mysql database. I have some complex data structures so I need to serialize those and save in the database.
I tried something like the following.
vector<int> vectorTest(10,100);
istream *blob = NULL;
ostringstream os;
int size_data = sizeof(vector<int>);
blob = new istringstream((char*)&vectorTest, istringstream::in | istringstream::binary);
string qry = "INSERT INTO vector(id,object) VALUES (?,?)";
prep_stmt = con->prepareStatement(qry);
prep_stmt->setInt(1,1);
prep_stmt->setBlob(2,blob);
prep_stmt->execute();
I just tried a small example here. However the vector object is not getting saved.
Alternatively can I can use the following approach.
ostringstream os;
int size_data = sizeof(vector<int>);
os.write((char*)&vectorTest, size_data);
However I don't know how to redirect the outputstream to an inputstream, because the setBlob() method needs an istream as the input parameter.
Can I know how to get any of this examples working ? If my approach is incorrect can anyone provide a code example or improve the given code segment ? Your immediate response is greatly appreciated.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的处理方式完全错误。这不是“序列化”,事实上它很可能与序列化相反——它只是试图将向量的原始内存转储写入数据库。想象一下,向量看起来像这样:
其中
elements
是一个动态分配的数组,用于保存向量的元素。最终写入数据库的是
num_elements
的值,然后是指针elements
的值。元素数据不会写入数据库,如果您要在程序的不同运行中将指针位置加载回向量中,则它指向的位置将包含垃圾。std::vector
也会发生同样的事情,因为它包含动态分配的内存,在您的情况下,这些内存将作为指针值写出,而其他内部状态在重新加载时可能无效。“序列化”的全部目的就是避免这种情况。序列化意味着将像这样的复杂对象转换为字节序列,其中包含重构原始对象所需的所有信息。您需要迭代向量并写出其中的每个整数。此外,您需要设计一种格式,当您读回它时,您可以确定一个整数的结束位置和下一个整数的开始位置。
例如,您可以用空格分隔整数,并像这样写出它们:
然后,当您读回这个 blob 时,您必须将该字符串解析回七个单独的整数,并将它们插入到新创建的向量中。
要写出的示例代码:
要读入的示例代码:
现在,从空间角度来看,这不一定是最有效的方法,因为这会在将整数插入数据库之前将它们转换为字符串,这将比 if 占用更多的空间您刚刚将它们作为二进制编码的整数插入。但是,在这种情况下,写出和读入的代码会更加复杂,因为您必须关心如何将整数打包为字节序列以及如何将字节序列解析为一堆整数。上面的代码使用字符串,以便标准库流可以使这部分变得简单,并更直接地演示序列化的含义。
You're going about this completely the wrong way. This isn't "serialization", in fact it's quite possibly the opposite of serialization -- it's just trying to write out a raw memory dump of a vector into the database. Imagine for a second that vector looked like something this:
Where
elements
is a dynamically allocated array that holds the elements of the vector.What you would end up writing out to your database is the value of
num_elements
and then the value of the pointerelements
. The element data would not be written to the database, and if you were to load the pointer location back into a vector on a different run of your program, the location it points to would contain garbage. The same sort of thing will happen withstd::vector
since it contains dynamically allocated memory that will will be written out as pointer values in your case, and other internal state that may not be valid if reloaded.The whole point of "serialization" is to avoid this. Serialization means turning a complex object like this into a sequence of bytes that contains all of the information necessary to reconstitute the original object. You need to iterate through the vector and write out each integer that's in it. And moreover, you need to devise a format where, when you read it back in, you can determine where one integer ends and the next begins.
For example, you might whitespace-delimit the ints, and write them out like this:
And then when you read this blob back in you would have to parse this string back into seven separate integers and insert them into a newly-created vector.
Example code to write out:
Example code to read in:
Now, this isn't necessarily the most efficient approach, space-wise, since this turns your integers into strings before inserting them into the database, which will take much more space than if you had just inserted them as binary-coded integers. However, the code to write out and read in would be more complex in that case because you would have to concern yourself with how you pack the integers into a byte sequence and how you parse a byte sequence into a bunch of ints. The code above uses strings so that the standard library streams can make this part easy and give a more straightforward demonstration of what serialization entails.
我写入 MySQL 数据库的解决方案是使用 Visitor 设计模式和抽象基类。我没有使用 BLOB 数据结构,而是使用字段(列):
我构建了一个层次结构,包括数字、布尔值和字符串字段。给定
Field
指针或引用,可以生成 SQLINSERT
和SELECT
语句。Record
将是字段的容器。只需为访问者提供一个for_each()
方法:通过使用更真实的Visitor 设计模式,将 SQL 细节移至访问者中。访问者通过调用的方法知道字段属性。这会将
Field
结构简化为仅具有get_field_name
和get_value_as_string
方法。我当前的障碍是使用 MySQL C++ Connector 和 wxWidgets 处理 BLOB 字段。
您可能还想在下一个问题中添加标签:
MySQL
和database
。My solution to writing to a MySQL database was to use the Visitor design pattern and an abstract base class. I did not use the BLOB data structure, instead used fields (columns):
I built a hierarchy including fields for numbers, bool, and strings. Given a
Field
pointer or reference, an SQLINSERT
andSELECT
statement can be generated.A
Record
would be a container of fields. Just provide afor_each()
method with a visitor:By using a more true Visitor design pattern, the SQL specifics are moved into the visitor. The visitor knows the field attributes due to the method called. This reduces the
Field
structure to having onlyget_field_name
andget_value_as_string
methods.My current hurdle is handling BLOB fields with MySQL C++ Connector and wxWidgets.
You may also want to add the tags:
MySQL
anddatabase
to your next questions.boost 有一个序列化库(我从未使用过它)
或 XML 或 JSON
boost has a serialization library (I have never used it tho)
or XML or JSON