ORM для C++: сравнение и примеры использования библиотек

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

ORM для C++: сравнение и примеры использования

В современной разработке на C++ работа с базами данных часто требует баланса между производительностью и удобством. В отличие от языков с богатой экосистемой ORM (например, Python или Java), C++ предлагает более узкий, но зрелый выбор инструментов. В этой статье мы сравним четыре популярные библиотеки: ODB, SQLiteCpp, Soci и sqlpp11. Рассмотрим их архитектуру, синтаксис, производительность и примеры кода.

1. ODB — промышленный стандарт

ODB — это полноценный ORM-компилятор для C++. Он генерирует код из заголовочных файлов, поддерживает реляционные базы (MySQL, PostgreSQL, SQLite, Oracle) и предоставляет мощный объектно-реляционный маппинг.

Ключевые особенности:

  • Автоматическая генерация кода через прекомпилятор (odb)
  • Поддержка наследования, полиморфизма, контейнеров STL
  • Ленивая загрузка, кэширование, транзакции

Пример: модель и запрос

// person.hxx
#pragma once
#include <string>
#include <odb/core.hxx>

#pragma db object
class Person {
public:
    Person() = default;
    Person(const std::string& name, int age)
        : name_(name), age_(age) {}

    const std::string& name() const { return name_; }
    int age() const { return age_; }

private:
    friend class odb::access;
    #pragma db id auto
    unsigned long id_;
    std::string name_;
    int age_;
};
// main.cpp
#include <odb/database.hxx>
#include <odb/sqlite/database.hxx>
#include "person.hxx"
#include "person-odb.hxx"

int main() {
    auto db = std::make_shared<odb::sqlite::database>("test.db");
    
    // Вставка
    Person p("Alice", 30);
    db->persist(p);
    
    // Запрос
    using query = odb::query<Person>;
    auto result = db->query<Person>(query::age > 25);
    for (const auto& person : result) {
        std::cout << person.name() << "\n";
    }
    return 0;
}

2. SQLiteCpp — лёгкая обёртка

SQLiteCpp — это минималистичная C++ обёртка над SQLite C API. Она не является полноценным ORM, но предоставляет удобный RAII-интерфейс для работы с SQL-запросами.

Ключевые особенности:

  • Зависимость только от SQLite3
  • Простой API: Database, Statement, Transaction
  • Поддержка prepared statements и биндинга параметров

Пример: вставка и выборка

#include <SQLiteCpp/Database.h>
#include <iostream>

int main() {
    SQLite::Database db("test.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
    
    // Создание таблицы
    db.exec("CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INT)");
    
    // Вставка с параметрами
    SQLite::Statement insert(db, "INSERT INTO person (name, age) VALUES (?, ?)");
    insert.bind(1, "Bob");
    insert.bind(2, 25);
    insert.exec();
    
    // Выборка
    SQLite::Statement query(db, "SELECT name, age FROM person WHERE age > ?");
    query.bind(1, 20);
    while (query.executeStep()) {
        std::cout << query.getColumn(0).getText() 
                  << " - " << query.getColumn(1).getInt() << "\n";
    }
    return 0;
}

3. Soci — универсальный доступ к БД

Soci — это библиотека для работы с различными базами данных (MySQL, PostgreSQL, SQLite, Oracle) через единый интерфейс. Она предоставляет как динамические запросы, так и поддержку ORM-подобного маппинга.

Ключевые особенности:

  • Поддержка нескольких бэкендов через плагины
  • Биндинг параметров через оператор << и into()
  • Поддержка транзакций и bulk-операций

Пример: работа с запросами

#include <soci/soci.h>
#include <iostream>

int main() {
    soci::session sql(soci::sqlite3, "test.db");
    
    sql << "CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INT)";
    
    // Вставка
    sql << "INSERT INTO person (name, age) VALUES (:name, :age)",
        soci::use("Charlie"), soci::use(35);                    

Рекомендаций