ORM für C++: Vergleich und Beispiele zur Nutzung
In der modernen C++-Entwicklung erfordert die Arbeit mit Datenbanken oft eine Balance zwischen Leistung und Komfort. Im Gegensatz zu Sprachen mit einem reichhaltigen ORM-Ökosystem (z. B. Python oder Java) bietet C++ eine engere, aber dennoch ausgereifte Auswahl an Werkzeugen. In diesem Artikel vergleichen wir vier beliebte Bibliotheken: ODB, SQLiteCpp, Soci und sqlpp11. Wir betrachten ihre Architektur, Syntax, Leistung und Codebeispiele.
1. ODB — Industriestandard
ODB ist ein vollwertiger ORM-Compiler für C++. Er generiert Code aus Header-Dateien, unterstützt relationale Datenbanken (MySQL, PostgreSQL, SQLite, Oracle) und bietet ein leistungsstarkes objektrelationales Mapping.
Hauptmerkmale:
- Automatische Codegenerierung durch einen Präcompiler (odb)
- Unterstützung für Vererbung, Polymorphismus, STL-Container
- Lazy Loading, Caching, Transaktionen
Beispiel: Modell und Abfrage
// person.hxx#pragma once#include <string>#include <odb/core.hxx>
#pragma db objectclass 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"); // Einfügen Person p("Alice", 30); db->persist(p); // Abfrage using query = odb::query<Person>; auto result = db->query<Person>(query::age > 25); for (const auto& person : result) { std::cout << person.name() << ""; } return 0;}2. SQLiteCpp — Leichtgewichtiger Wrapper
SQLiteCpp ist ein minimalistischer C++-Wrapper um das SQLite C API. Es ist kein vollwertiges ORM, bietet aber eine praktische RAII-Schnittstelle für die Arbeit mit SQL-Abfragen.
Hauptmerkmale:
- Nur Abhängigkeit von SQLite3
- Einfaches API: Database, Statement, Transaction
- Unterstützung für Prepared Statements und Parameterbindung
Beispiel: Einfügen und Abfragen
#include <SQLiteCpp/Database.h>#include <iostream>
int main() { SQLite::Database db("test.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); // Tabelle erstellen db.exec("CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INT)"); // Einfügen mit Parametern SQLite::Statement insert(db, "INSERT INTO person (name, age) VALUES (?, ?)"); insert.bind(1, "Bob"); insert.bind(2, 25); insert.exec(); // Abfrage 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() << ""; } return 0;}3. Soci — Universeller Datenbankzugriff
Soci ist eine Bibliothek für die Arbeit mit verschiedenen Datenbanken (MySQL, PostgreSQL, SQLite, Oracle) über eine einheitliche Schnittstelle. Sie bietet sowohl dynamische Abfragen als auch Unterstützung für ORM-ähnliches Mapping.
Hauptmerkmale:
- Unterstützung mehrerer Backends über Plugins
- Parameterbindung über den Operator << und into()
- Unterstützung für Transaktionen und Bulk-Operationen
Beispiel: Arbeiten mit Abfragen
Auch in der Bibliothek
PHP-CS-Fixer für PHP: Komplettguide mit Beispielen
Caching in C++: Redis, Memcached und integrierte Lösungen
Media3 / ExoPlayer für Kotlin: Komplettes Tutorial mit Beispielen
GraphQL.js für JavaScript (Node.js): Vollständige Anleitung mit Beispielen
E-Mail-Versand mit Rust: Die Bibliotheken lettre und mailparse für die E-Mail-Verarbeitung
Empfehlungen