C++ ORM:比较与使用示例
在现代 C++ 开发中,与数据库的交互常常需要在性能与便利性之间取得平衡。与拥有丰富 ORM 生态系统的语言(如 Python 或 Java)不同,C++ 提供的工具选择范围更窄,但更加成熟。本文将比较四个流行的库:ODB、SQLiteCpp、Soci 和 sqlpp11。我们将探讨它们的架构、语法、性能以及代码示例。
1. ODB —— 工业标准
ODB 是一个完整的 C++ ORM 编译器。它从头文件生成代码,支持关系型数据库(MySQL、PostgreSQL、SQLite、Oracle),并提供强大的对象关系映射功能。
主要特性:
- 通过预编译器 (odb) 自动生成代码
- 支持继承、多态、STL 容器
- 延迟加载、缓存、事务
示例:模型与查询
// 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"); // 插入 Person p("Alice", 30); db->persist(p); // 查询 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 —— 轻量级封装
SQLiteCpp 是一个极简的 C++ 封装,基于 SQLite C API。它不是一个完整的 ORM,但为执行 SQL 查询提供了便捷的 RAII 接口。
主要特性:
- 仅依赖 SQLite3
- 简单的 API:Database、Statement、Transaction
- 支持预编译语句和参数绑定
示例:插入与查询
#include <SQLiteCpp/Database.h>#include <iostream>
int main() { SQLite::Database db("test.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); // 创建表 db.exec("CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INT)"); // 带参数的插入 SQLite::Statement insert(db, "INSERT INTO person (name, age) VALUES (?, ?)"); insert.bind(1, "Bob"); insert.bind(2, 25); insert.exec(); // 查询 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 —— 通用数据库访问
Soci 是一个用于通过统一接口与多种数据库(MySQL、PostgreSQL、SQLite、Oracle)交互的库。它既支持动态查询,也支持类似 ORM 的映射功能。
主要特性:
- 通过插件支持多种后端
- 通过 << 和 into() 操作符进行参数绑定
- 支持事务和批量操作
示例:查询操作
图书馆中也有
推荐