ORM pour C++ : comparaison et exemples d'utilisation (ODB, SOCI, SQLiteCpp)

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

ORM pour C++ : comparaison et exemples d'utilisation



Contrairement aux langages à typage dynamique (Python, PHP), le C++ ne dispose pas de support intégré pour la réflexion et la métaprogrammation suffisant pour créer un ORM "magique". Néanmoins, il existe plusieurs solutions puissantes qui automatisent le travail avec les bases de données. Dans cet article, nous comparerons trois bibliothèques populaires : ODB, SOCI et SQLiteCpp, et donnerons des exemples de leur utilisation.



Critères de comparaison

Lors du choix d'un ORM pour C++, il convient de prêter attention à :

  • Type de génération de code — générateur externe ou templates C++.
  • Support des SGBD — SQLite, PostgreSQL, MySQL, Oracle.
  • Performances — surcoût lié au mapping.
  • Complexité d'intégration — nécessite-t-il une étape de compilation séparée.


1. ODB — ORM industriel pour C++

ODB est un ORM commercial (avec une version gratuite pour l'open-source) basé sur la génération de code à partir de fichiers d'en-tête annotés. Il prend en charge les bases de données relationnelles (SQLite, PostgreSQL, MySQL, Oracle) et même NoSQL (MongoDB).



Exemple avec ODB (SQLite)

D'abord, on déclare la classe d'entité :

#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_;};


Utilisation :

#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();}


Avantages : modèle objet complet, support des relations, chargement paresseux. Inconvénients : nécessite un générateur de code (étape de compilation), licence pour usage commercial.



2. SOCI — "couche d'accès aux données" légère

SOCI n'est pas un ORM complet, mais une bibliothèque pour travailler avec SQL depuis C++, qui offre une syntaxe pratique pour exécuter des requêtes et mapper les résultats. Elle fonctionne avec SQLite, PostgreSQL, MySQL, Oracle et ODBC.



Exemple avec 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)";

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

// Sélection avec mapping dans une structure 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; }}


Avantages : intégration facile, pas de génération de code, support des requêtes préparées. Inconvénients : pas de mapping automatique des objets

Recommendations