查询数据库以在 C++ 中创建自定义类集合的最佳方法

Best approach to query a database to create a collection of a custom class in C++

本文关键字:集合 最佳 方法 自定义 创建 数据库 C++ 查询      更新时间:2023-10-16

我是通过 c++ 与数据库接口的新手,想知道执行以下操作的最佳方法是什么:

我有一个对象,其中包含我提前定义的成员变量,以及我需要从给定已知变量的数据库中提取的成员变量。 例如:

class DataObject
{
public:
int input1;
string input2;
double output1;
DataObject(int Input1, string Input2) :
input1(Input1), input2(Input2)
{
output1 = Initializer(input1,input2);
}
private:
Initializer(int, string);
static RecordSet rs; //I am just guessing the object would be called RecordSet
}

现在,我可以执行以下操作:

std::vector<DataObject> v;
for (int n = 0; n <= 10; ++n)
for (char w = 'a'; w <= 'z'; ++w)
v.push_back(DataObject{n,z});

并获取数据对象的初始化向量。 在后台,初始值设定项将检查 rs 是否已具有数据。 如果没有,它将连接到数据库并查询类似以下内容:select input1, input2, output1 from ... where input1 between 1 and 10 and input 2 between 'a' and 'z',然后开始初始化每个DataObject,给定每对input1input2output1

这在 C# 中非常简单,但从我在网上找到的代码示例中,它在C++中看起来非常丑陋。 我被困在两件事上。 如前所述,我对C++中的数据库接口完全陌生,有很多方法可供选择,但我想磨练一种真正适合我目的的特定方法。 此外 - 这就是目的 - 我正在尝试使用静态数据集在单个查询中提取数据,而不是为每个 input1/input2 组合运行新查询;更好的是,有没有办法将数据库结果直接写入新创建的DataObject,而不是在某个临时 RecordSet 对象中进行进站。

总结和澄清:我在关系数据库上有数据库,我正在尝试提取数据并将其存储到对象集合中。 我该怎么做? 任何提示/方向 - 我非常有义务。

编辑8/16/17:经过一些研究和试验,我想出了以下内容

因此,我通过使用put_CursorLocation设置为adUseServerADORecordset取得了进展:

rs->put_CursorLocation(adUseServer)

我的理解是,通过使用此设置,查询结果存储在服务器上,客户端仅获取rs指向的当前行。

所以我从行中获取数据并当场创建 DataObject,将其emplace_back向量中,最后调用rs->MoveNext()获取下一行并重复直到到达末尾。部分示例如下:

std::vector<DataObject> v;
DataObject::rs.Open(connString,Sql); // Connection for wrapper class
for (int n = 0; n <= 10; ++n)
for (char w = 'a'; w <= 'z'; ++w)
v.emplace_back(DataObject{n,z});
// Somewhere else...
void DataObject::Initializer(int a, string b) {
int ra; string rb; double rc;
// For simplicity's sake, let's assume the result set is ordered
//  in the same way as the for-loop, and that no data is missing.
//  So the below sanity-check would be unnecessary, but included.
while (!rs.IsEOF())
{
// Let's assume I defined these 'Get' functions
ra = rs.Get<int>("Input1");
rb = rs.Get<string>("Input2");
rc = rs.Get<double>("Output1");
rs.MoveNext();
if (ra == a && rb == b) break;
}
return rc;
}
// Constructor for RecordSet:
RecordSet::RecordSet()
{
HRESULT hr = rs_.CoCreateInstance(CLSID_CADORecordset);
ATLENSURE_SUCCEEDED(hr);
rs_->put_CursorLocation(adUseServer);
}

现在我希望我正确地解释了它是如何工作的;否则,这将是一大堆大惊小怪的事情。显然,我不是 ADO 或 .Net 专家,但我希望有人可以插话确认这确实是这样工作的,也许可以对这个主题有更多的了解。就我而言,我使用VS2015的诊断工具测试了内存使用情况,使用adUseClient时堆似乎要大得多。如果我的猜想是正确的,那么为什么有人会选择使用adUseClient或任何其他选择,而不是adUseServer.

我想到两个选项:按成员类型和 BLOB。

对于类,我建议每个类实例一行,每个成员一列。 按数据库搜索支持的数据类型。 有一些常见的类型。

另一种方法是使用 BLOB(二进制大型 OBject(数据类型。 这是一种"二进制"数据类型,用于按原样存储数据。

可以将 BLOB 类型用于数据类型不受支持的成员。

您可以通过研究"数据库规范化"或"数据库规范形式"来变得更加复杂。