Дизайн класса C++ из схемы базы данных

Я пишу сценарий Perl для анализа схемы базы данных mysql и создания классов C++ при необходимости. Мой вопрос довольно простой, но это то, чего я раньше не делал и не знаю общепринятой практики. Любой объект любого из созданных классов должен иметь методы "get" для заполнения этой информации. Итак, у меня двоякий вопрос:

  1. Имеет ли смысл вызывать все методы get в конструкторе, чтобы у объекта сразу были данные? В некоторых классах их будет много, так что при необходимости тоже может иметь смысл. У меня сейчас два конструктора. Тот, который заполняет данные, а другой - нет.
  2. Должен ли я также иметь другой метод "get", который извлекает копию данных объекта, а не копию db.

Я могу пойти обоими путями на №1 и склоняюсь к положительному ответу на №2. Любые советы, указатели будут очень признательны.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
3 103
5

Ответы 5

есть существующие инструменты, которые меняют db на java (и, возможно, на другие языки). рассмотрите возможность использования одного из них и преобразования его в C++.

Я бы не рекомендовал использовать ваши методы get в базе данных, за исключением случаев, когда это абсолютно необходимо для вашей конкретной проблемы. Это приводит к гораздо большему количеству мест, где что-то может пойти не так, и, вероятно, к множеству ненужных чтений в вашей БД, и может непреднамеренно привязать ваши объекты к специфическим для базы данных функциям, теряя многие преимущества многоуровневой архитектуры. Что касается вашей модели предметной области, то базы данных не существует.

редактировать - это для №2 (очевидно). Для №1 я бы сказал «нет» по многим из тех же причин.

Сначала поймите, что вы заново изобретаете колесо. Практически на каждом языке существует ряд достойных библиотек объектно-реляционного сопоставления для доступа к базе данных. Для C / C++ вы можете посмотреть:

http://trac.butterfat.net/public/StactiveRecord
http://debea.net/trac

Хорошо, если это не так, вы, вероятно, захотите создать в своем классе статический метод с именем find или search, который является фабрикой для создания объектов и выбора их из базы данных:

Artist MJ = Artist::Find("Michael Jackson");
MJ->set("relevant", "no");
MJ->save();

Обратите внимание на метод сохранения, который затем берет измененный объект и сохраняет его обратно в базу данных. Если вы действительно хотите создать новую запись, вы должны использовать метод new, который будет создавать пустой объект:

Artist StackOverflow = Artist->new();
StackOverflow->set("relevant", "yes");
StackOverflow->save();

Обратите внимание на то, что методы set и get здесь просто устанавливаются и получают значения из объекта, а не из базы данных. Чтобы фактически сохранить элементы в базе данных, вам нужно будет использовать статический метод Find или метод объекта save.

Да, я видел, как несколько (sql2class) были одними из них. Я не особо рассматривал Active Record или ORM, но, полагаю, это возможно.

KlobY 18.09.2008 00:03

Обычно самая дорогостоящая часть приложения - это обращение к базе данных и обратно, поэтому было бы гораздо эффективнее заполнять все элементы данных из одного запроса, чем делать их по одному, либо по мере необходимости, либо из ваш конструктор. После того, как вы заплатили за поездку туда и обратно, вы также можете окупить свои деньги.

Кроме того, как правило, ваши методы get * должны быть объявлены как const, что означает, что они не изменяют базовый объект, поэтому их выход в базу данных для заполнения объекта нарушит это (что вы могли бы разрешить, сделав переменные-члены изменяемый, но это в основном нарушит цель const).

Чтобы разбить все на конкретные шаги, я бы порекомендовал:

  • Пусть ваш конструктор вызовет отдельный метод init (), который запрашивает базу данных и заполняет элементы данных вашего объекта.
  • Объявите свои методы get * как const и просто попросите их вернуть элементы данных.

Я согласен на 100% насчет поездок по db. Предостережение заключается в том, что будет несколько исполняемых файлов, использующих эти классы, и большое количество данных будет заполняться без надобности. Вот тут я и начинаю чесать в затылке. Большая часть будет доступна только для чтения.

KlobY 18.09.2008 00:08

Я должен пояснить, что, говоря, что разные исполняемые файлы будут использовать класс для разных подмножеств полей (столбцов в базе данных). Спасибо за ответ.

KlobY 18.09.2008 00:10

Я бы все же сказал, что если мы не говорим об очень сложных или больших типах данных (например, 2 МБ CLOB), стоимость множественных обращений к базе данных затмит затраты на заполнение данных, которые вам не понадобятся довольно быстро.

JohnMcG 18.09.2008 18:33

Другой альтернативой было бы не автоматизировать создание классов, а вместо этого создавать отдельные классы, содержащие только элементы данных, которые интересуют отдельные исполняемые файлы, чтобы эти классы извлекали только необходимые данные.

Однако не знаю, о скольких таблицах мы говорим, так что это может резко увеличить объем вашего проекта.

Другие вопросы по теме