ORM pour C++ : comparaison et exemples d'utilisation
Dans le développement moderne en C++, le travail avec les bases de données nécessite souvent un équilibre entre performances et commodité. Contrairement aux langages dotés d'un riche écosystème ORM (comme Python ou Java), C++ propose un choix plus restreint mais mature d'outils. Dans cet article, nous comparons quatre bibliothèques populaires : ODB, SQLiteCpp, Soci et sqlpp11. Nous examinons leur architecture, leur syntaxe, leurs performances et des exemples de code.
1. ODB — le standard industriel
ODB est un compilateur ORM complet pour C++. Il génère du code à partir de fichiers d'en-tête, prend en charge les bases de données relationnelles (MySQL, PostgreSQL, SQLite, Oracle) et offre un puissant mappage objet-relationnel.
Caractéristiques clés :
- Génération automatique de code via un précompilateur (odb)
- Prise en charge de l'héritage, du polymorphisme, des conteneurs STL
- Chargement paresseux, mise en cache, transactions
Exemple : modèle et requête
// 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"); // Insertion Person p("Alice", 30); db->persist(p); // Requête 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 — une enveloppe légère
SQLiteCpp est une enveloppe C++ minimaliste autour de l'API C de SQLite. Ce n'est pas un ORM complet, mais il offre une interface RAII pratique pour travailler avec des requêtes SQL.
Caractéristiques clés :
- Dépendance uniquement à SQLite3
- API simple : Database, Statement, Transaction
- Prise en charge des instructions préparées et de la liaison de paramètres
Exemple : insertion et sélection
#include <SQLiteCpp/Database.h>#include <iostream>
int main() { SQLite::Database db("test.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); // Création de la table db.exec("CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INT)"); // Insertion avec paramètres SQLite::Statement insert(db, "INSERT INTO person (name, age) VALUES (?, ?)"); insert.bind(1, "Bob"); insert.bind(2, 25); insert.exec(); // Sélection 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 — accès universel aux bases de données
Soci est une bibliothèque pour travailler avec diverses bases de données (MySQL, PostgreSQL, SQLite, Oracle) via une interface unifiée. Elle offre à la fois des requêtes dynamiques et la prise en charge d'un mappage de type ORM.
Caractéristiques clés :
- Prise en charge de plusieurs backends via des plugins
- Liaison de paramètres via l'opérateur << et into()
- Prise en charge des transactions et des opérations en masse
Exemple : travail avec les requêtes
Aussi dans la bibliothèque
Génération de PDF en C# (.NET) : aperçu des bibliothèques et outils
Client HTTP pour Go (Golang) : top bibliothèques pour le travail réseau
Configuration des applications Swift (iOS/macOS) : bonnes pratiques et outils
Java Image I/O API : redimensionnement et recadrage d'images | Guide
Client HTTP pour JavaScript (Node.js) : top bibliothèques pour travailler avec les API
Recommendations