ORM para C++: comparação e exemplos de uso
No desenvolvimento moderno em C++, o trabalho com bancos de dados frequentemente exige um equilíbrio entre desempenho e conveniência. Diferente de linguagens com um ecossistema rico de ORM (como Python ou Java), o C++ oferece uma seleção mais restrita, porém madura, de ferramentas. Neste artigo, compararemos quatro bibliotecas populares: ODB, SQLiteCpp, Soci e sqlpp11. Analisaremos sua arquitetura, sintaxe, desempenho e exemplos de código.
1. ODB — padrão industrial
ODB é um compilador ORM completo para C++. Ele gera código a partir de arquivos de cabeçalho, suporta bancos de dados relacionais (MySQL, PostgreSQL, SQLite, Oracle) e fornece um mapeamento objeto-relacional poderoso.
Principais características:
- Geração automática de código via pré-compilador (odb)
- Suporte a herança, polimorfismo, contêineres STL
- Carregamento preguiçoso, cache, transações
Exemplo: modelo e consulta
// 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"); // Inserção Person p("Alice", 30); db->persist(p); // Consulta 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 — wrapper leve
SQLiteCpp é um wrapper C++ minimalista sobre a API C do SQLite. Não é um ORM completo, mas fornece uma interface RAII conveniente para trabalhar com consultas SQL.
Principais características:
- Dependência apenas do SQLite3
- API simples: Database, Statement, Transaction
- Suporte a prepared statements e vinculação de parâmetros
Exemplo: inserção e consulta
#include <SQLiteCpp/Database.h>#include <iostream>
int main() { SQLite::Database db("test.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); // Criação de tabela db.exec("CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INT)"); // Inserção com parâmetros SQLite::Statement insert(db, "INSERT INTO person (name, age) VALUES (?, ?)"); insert.bind(1, "Bob"); insert.bind(2, 25); insert.exec(); // Consulta 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 — acesso universal a BD
Soci é uma biblioteca para trabalhar com diversos bancos de dados (MySQL, PostgreSQL, SQLite, Oracle) através de uma interface unificada. Ela oferece tanto consultas dinâmicas quanto suporte a mapeamento semelhante a ORM.
Principais características:
- Suporte a múltiplos backends via plugins
- Vinculação de parâmetros através do operador << e into()
- Suporte a transações e operações em lote
Exemplo: trabalho com consultas
Também na biblioteca
Recommendations