我需要将 QRect 存储在 Sqlite 数据库中。(我已经四处搜索,但没有看到任何关于此的内容)
Qt/QSQLITE 是否会自动将 QRect 转换为 QVariant 并处理所需的任何分解,还是我必须自己执行此操作并将原点和大小值存储在四个单独的字段中?
如果是这样,并将其推广到其他 Qt 数据类型,是否可以存储 QVector、QList?我会在我的表定义中将这些(和 QRect 等)定义为 BLOB 类型吗?
SQLite 是一个关系数据库,那些东西不能直接存储 C++ 对象。
实际上,C++ 对象模型不允许完全透明的持久性,但您可以尝试使用专门的工具或库来接近一些。然而,重要的一点是对象本身必须设计为支持持久性。
如果您不需要透明的持久性,而只需要显式存储/检索对象,那么您可以选择您喜欢的序列化方法(例如,使用单个字符串,或为属性使用单独的字段)。每种方法都有优点和缺点,具体取决于您想要对数据库执行的操作(例如,您想要执行什么样的搜索或更新)。
C++ 的不幸之处在于它的元编程能力非常差(仅比 C 好一点),例如内省是不可能的。
这意味着您需要为需要支持的每个类编写序列化代码,或者您需要找到/购买一个外部工具,查看类定义.h
将为您生成所需的代码。它必须是一个外部工具,因为序列化超出了模板元编程非常有限的范围。
Qt 本身已经有一些专门的序列化机制QDataStream
,因此您可以将其用于您正在寻找的内容:例如QRect
是可序列化的,QList<T>
如果T
是,则可序列化。
使用它需要先序列化QByteArray
,然后将 blob 存储在 SQLite 中。比如写完之后
template<typename T>
QByteArray serialize(const T& x)
{
QByteArray ba;
QDataStream s(&ba, QIODevice::WriteOnly);
s << x;
return ba;
}
template<typename T>
T deserialize(QByteArray& ba)
{
QDataStream s(&ba, QIODevice::ReadOnly);
T res; s >> res;
return res;
}
您可以将对象直接序列化为QByteArray
with
QByteArray ba = serialize(x);
你可以反序列化它
X x = deserialize<X>(ba);
您可以将 QRect 存储在另一个表中,该表将(例如)id, x, y, h, w
作为列。
当您要存储QRect
时,在新创建的表中创建新行,获取它id
并将其存储在目标表中。
QVector
并且QList
是容器,其中QRect
是一个简单的结构。您可以将其保存在单独的表中(每个条目一行),或者您可以将容器序列化并将其保存在 BLOB 列中。
不,你必须自己做。如何将 QRect 存储到 Sqlite 取决于您和您的要求。存储单个值,将整个数据类型序列化为 TEXT、BLOB 或使用 QDataStream 的任何内容……最适合您的。