oop — лучший подход для запроса базы данных для создания коллекции пользовательского класса в Stack Overflow

Я новичок в интерфейсах с базами данных через 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});

И получить инициализированный вектор DataObjects. За кулисами Initializer проверит, есть ли у rs данные. Если нет, он подключится к базе данных и запросит что-то вроде: select input1, input2, output1 from ... where input1 between 1 and 10 and input 2 between 'a' and 'z', а затем начать инициализацию каждого DataObject с output1 учитывая каждую пару input1 а также input2,

Это было бы очень просто в C #, но из примеров кода, которые я нашел в Интернете, это выглядит совершенно безобразно в C ++. Я застрял на двух вещах. Как указывалось ранее, я совершенно новичок в интерфейсах баз данных в C ++, и есть так много методов, из которых можно выбирать, но я хотел бы отточить конкретный метод, который действительно соответствует моей цели. Более того — и это цель — я пытаюсь использовать статический набор данных для извлечения данных в одном запросе, а не запускать новый запрос для каждой комбинации input1 / input2; еще лучше, есть ли способ, чтобы результаты базы данных записывались непосредственно во вновь созданный DataObjects вместо того, чтобы делать пит-стоп в каком-то временном объекте RecordSet.

Подведем итоги и уточню: у меня есть база данных в реляционной базе данных, и я пытаюсь извлечь данные и сохранить их в виде коллекции объектов. Как мне это сделать? Любые советы / направления — я очень благодарен.

РЕДАКТИРОВАТЬ 16/16/17: после некоторых исследований и испытаний я придумал ниже

Так что я добился прогресса, используя ADORecordset с put_CursorLocation установлен в adUseServer:

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,

0

Решение

Я думаю о двух вариантах: по типу члена и BLOB.

Для классов я рекомендую одну строку на экземпляр класса с одним столбцом на член. Поиск поддерживаемых типов данных по вашей базе данных. Есть несколько распространенных типов.

Другой метод заключается в использовании типа данных BLOB (большой двоичный объект). Это «двоичный» тип данных, используемый для хранения данных как есть.

Вы можете использовать тип BLOB для элементов с неподдерживаемыми типами данных.

Вы можете сделать более сложным, исследуя «Нормализация базы данных» или «Нормальные формы базы данных».

0

Другие решения

Других решений пока нет …