Введение в работу с базами данных на C++
Современные приложения редко обходятся без хранения данных. C++ — мощный язык системного программирования, который отлично подходит для высоконагруженных проектов, работающих с базами данных. В этой статье мы разберем, как подключиться к двум популярным СУБД — реляционной PostgreSQL и документо-ориентированной MongoDB — и выполнить базовые операции (CRUD).
Материал рассчитан на начинающих: вы узнаете, какие библиотеки нужны, как их установить, и увидите готовые примеры кода. После прочтения вы сможете самостоятельно интегрировать C++ с любой из этих баз данных.
PostgreSQL в C++: реляционный подход
PostgreSQL — одна из самых надежных реляционных СУБД с открытым исходным кодом. Для работы с ней из C++ используется библиотека libpqxx — официальная обертка над C-библиотекой libpq.
Установка libpqxx
В Linux (Ubuntu/Debian) установка выполняется одной командой:
sudo apt-get install libpqxx-dev
Для Windows можно использовать vcpkg:
vcpkg install libpqxx
Подключение и выполнение запроса
Рассмотрим простейший пример: подключение к базе данных, создание таблицы и вставка данных.
#include <iostream>
#include <pqxx/pqxx>
int main() {
try {
// Подключение к БД (замените параметры на свои)
pqxx::connection conn("dbname=testdb user=postgres password=secret hostaddr=127.0.0.1 port=5432");
if (conn.is_open()) {
std::cout << "Подключение к PostgreSQL успешно!" << std::endl;
}
// Создание транзакции
pqxx::work txn(conn);
// Создание таблицы
txn.exec("CREATE TABLE IF NOT EXISTS users ("
"id SERIAL PRIMARY KEY, "
"name VARCHAR(100) NOT NULL, "
"email VARCHAR(100) UNIQUE NOT NULL)");
// Вставка данных
txn.exec("INSERT INTO users (name, email) VALUES "
"('Иван Петров', 'ivan@example.com'), "
"('Мария Смирнова', 'maria@example.com')");
// Фиксация транзакции
txn.commit();
std::cout << "Данные успешно добавлены!" << std::endl;
} catch (const std::exception &e) {
std::cerr << "Ошибка: " << e.what() << std::endl;
return 1;
}
return 0;
}
Чтение данных (SELECT)
Для выборки данных используйте итератор результата:
pqxx::work txn(conn);
pqxx::result result = txn.exec("SELECT id, name, email FROM users");
for (const auto &row : result) {
int id = row["id"].as<int>();
std::string name = row["name"].as<std::string>();
std::string email = row["email"].as<std::string>();
std::cout << id << " | " << name << " | " << email << std::endl;
}
Важно: Всегда используйте параметризованные запросы для защиты от SQL-инъекций:
txn.exec_params("INSERT INTO users (name, email) VALUES ($1, $2)",
"Алексей", "alex@example.com");
MongoDB в C++: документо-ориентированный подход
MongoDB — NoSQL база данных, хранящая данные в формате BSON (бинарный JSON). Для C++ существует официальный драйвер mongocxx.
Установка mongocxx
Установка на Linux (требуется предварительно установить MongoDB C Driver):
sudo apt-get install libmongoc-dev libbson-dev
git clone https://github.com/mongodb/mongo-cxx-driver.git
cd mongo-cxx-driver
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBSONCXX_POLY_USE_MNMLSTC=ON
make -j4
sudo make install
Подключение и CRUD-операции
Следующий код демонстрирует подключение к MongoDB и базовые операции:
#include <iostream>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>
int main() {
try {
// Инициализация драйвера (выполняется один раз)
mongocxx::instance instance{};
// Подключение к localhost:27017
mongocxx::client client{mongocxx::uri{"mongodb://localhost:27017"}};
// Выбор базы данных и коллекции
auto db = client["testdb"];
auto collection = db["users"];
// Вставка документа
bsoncxx::builder::stream::document document{};
document << "name" << "Иван Петров"
<< "email" << "ivan@example.com"
<< "age" << 30;
auto result = collection.insert_one(document.view());
std::cout << "Вставлен документ с ID: "
<< result->inserted_id().get_oid().value.to_string()
<< std::endl;
// Поиск документа
auto cursor = collection.find({});
for (auto&& doc : cursor) {
std::cout << bsoncxx::to_json(doc) << std::endl;
}
} catch (const std::exception &e) {
std::cerr << "Ошибка: " << e.what() << std::endl;
return 1;
}
return 0;
}
Фильтрация и обновление
Пример поиска по условию и обновления документа:
// Поиск пользователя по email
auto filter = bsoncxx::builder::stream::document{}
<< "email" << "ivan@example.com" << bsoncxx::builder::stream::finalize;
auto result_doc = collection.find_one(filter.view());
if (result_doc) {
std::cout << "Найден: " << bsoncxx::to_json(*result_doc) << std::endl;
}
// Обновление: увеличить age на 1
auto update = bsonc