ORM für C++: Vergleich und Anwendungsbeispiele (ODB, SOCI, SQLiteCpp)

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

ORM für C++: Vergleich und Anwendungsbeispiele



Im Gegensatz zu Sprachen mit dynamischer Typisierung (Python, PHP) verfügt C++ nicht über eine eingebaute Unterstützung für Reflexion und Metaprogrammierung, die ausreicht, um ein "magisches" ORM zu erstellen. Dennoch gibt es mehrere leistungsstarke Lösungen, die die Arbeit mit Datenbanken automatisieren. In diesem Artikel vergleichen wir drei beliebte Bibliotheken: ODB, SOCI und SQLiteCpp, und geben Beispiele für ihre Verwendung.



Vergleichskriterien

Bei der Auswahl eines ORM für C++ sollte man auf Folgendes achten:

  • Art der Codegenerierung — externer Generator oder C++-Vorlagen.
  • DBMS-Unterstützung — SQLite, PostgreSQL, MySQL, Oracle.
  • Leistung — Overhead durch die Abbildung.
  • Integrationskomplexität — ist ein separater Build-Schritt erforderlich.


1. ODB — Industrielles ORM für C++

ODB ist ein kommerzielles ORM (mit einer kostenlosen Version für Open-Source), das auf der Codegenerierung aus annotierten Header-Dateien basiert. Es unterstützt relationale Datenbanken (SQLite, PostgreSQL, MySQL, Oracle) und sogar NoSQL (MongoDB).



Beispiel mit ODB (SQLite)

Zunächst deklarieren wir eine Entitätsklasse:

#include <odb/core.hxx>

#pragma db objectclass Person {public: Person(const std::string& name, int age) : name_(name), age_(age) {}

unsigned long id() const { return id_; } 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_;};


Verwendung:

#include <odb/database.hxx>#include <odb/sqlite/database.hxx>#include <odb/transaction.hxx>#include "person.hxx"#include "person-odb.hxx"

int main() { auto db = std::make_shared<odb::sqlite::database>("test.db"); odb::transaction t(db->begin());

Person p("Alice", 30); db->persist(p); // INSERT

auto result = db->query<Person>( odb::query<Person>::age > 25); for (const auto& person : result) { std::cout << person.name() << std::endl; } t.commit();}


Vorteile: vollständiges Objektmodell, Unterstützung für Beziehungen, Lazy Loading. Nachteile: Codegenerator erforderlich (Build-Schritt), kommerzielle Lizenz.



2. SOCI — Leichtgewichtige "Data Access Layer"

SOCI ist kein vollwertiges ORM, sondern eine Bibliothek für die Arbeit mit SQL aus C++, die eine bequeme Syntax zum Ausführen von Abfragen und zum Abbilden von Ergebnissen bietet. Sie funktioniert mit SQLite, PostgreSQL, MySQL, Oracle und ODBC.



Beispiel mit SOCI

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

struct Person { int id; std::string name; int age;};

int main() { soci::session sql(soci::sqlite3, "test.db"); sql << "CREATE TABLE IF NOT EXISTS person (" "id INTEGER PRIMARY KEY, " "name TEXT, age INTEGER)";

// Einfügen sql << "INSERT INTO person (name, age) VALUES (:name, :age)", soci::use("Bob"), soci::use(25);

// Abfrage mit Abbildung in eine Struktur Person p; soci::indicator ind; sql << "SELECT id, name, age FROM person WHERE id = :id", soci::use(1), soci::into(p.id), soci::into(p.name, ind), soci::into(p.age);

if (ind == soci::i_ok) { std::cout << p.name << " " << p.age << std::endl; }}


Vorteile: einfache Integration, keine Codegenerierung, Unterstützung für Prepared Statements. Nachteile: keine automatische Objektabbildung

Empfehlungen