ORM para C++: comparación y ejemplos de uso (ODB, SOCI, SQLiteCpp)

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

ORM para C++: comparación y ejemplos de uso



A diferencia de los lenguajes con tipado dinámico (Python, PHP), C++ no tiene soporte incorporado de reflexión y metaprogramación suficiente para crear un ORM "mágico". Sin embargo, existen varias soluciones potentes que automatizan el trabajo con bases de datos. En este artículo compararemos tres bibliotecas populares: ODB, SOCI y SQLiteCpp, y proporcionaremos ejemplos de su uso.



Criterios de comparación

Al elegir un ORM para C++, se debe prestar atención a:

  • Tipo de generación de código — generador externo o plantillas de C++.
  • Soporte de SGBD — SQLite, PostgreSQL, MySQL, Oracle.
  • Rendimiento — sobrecarga del mapeo.
  • Complejidad de integración — si se requiere un paso de compilación adicional.


1. ODB — ORM industrial para C++

ODB es un ORM comercial (con versión gratuita para código abierto) basado en la generación de código a partir de archivos de cabecera anotados. Soporta bases de datos relacionales (SQLite, PostgreSQL, MySQL, Oracle) e incluso NoSQL (MongoDB).



Ejemplo con ODB (SQLite)

Primero declaramos la clase entidad:

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


Uso:

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


Ventajas: modelo de objetos completo, soporte de relaciones, carga diferida. Desventajas: requiere un generador de código (paso de compilación), licencia para uso comercial.



2. SOCI — "capa de acceso a datos" ligera

SOCI no es un ORM completo, sino una biblioteca para trabajar con SQL desde C++ que proporciona una sintaxis conveniente para ejecutar consultas y mapear resultados. Funciona con SQLite, PostgreSQL, MySQL, Oracle y ODBC.



Ejemplo con 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)";

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

// Consulta con mapeo a estructura 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; }}


Ventajas: integración sencilla, sin generación de código, soporte de prepared statements. Desventajas: no tiene mapeo automático de objetos.

Recommendations