最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ ODB ORM 從入門到實戰(zhàn)應(yīng)用(ODB使用)

 更新時間:2025年12月01日 11:14:05   作者:編程小Y  
ODB 作為 C++ 的高效 ORM 框架,通過編譯期代碼生成實現(xiàn)了對象與數(shù)據(jù)庫的無縫映射,既保留了 C++ 的性能優(yōu)勢,又簡化了數(shù)據(jù)庫操作,本文從基礎(chǔ)概念到實戰(zhàn)開發(fā),全面講解ODB的使用,感興趣的朋友一起看看吧

ODB(Object-Relational Mapping)是 C++ 領(lǐng)域成熟的 ORM 框架,由 Code Synthesis 開發(fā),能將 C++ 對象與關(guān)系型數(shù)據(jù)庫(如 MySQL、PostgreSQL、SQLite)無縫映射,避免手動編寫 SQL 語句,大幅提升數(shù)據(jù)庫開發(fā)效率。本文從基礎(chǔ)概念到實戰(zhàn)開發(fā),全面講解 ODB 的使用。

一、ODB 核心概念與環(huán)境準備

1. ORM 與 ODB 簡介

ORM(對象關(guān)系映射)的核心是 “對象 - 表映射”:C++ 類對應(yīng)數(shù)據(jù)庫表,類成員對應(yīng)表字段,對象實例對應(yīng)表中的行。ODB 作為 C++ 專屬 ORM,具備以下特性:

  • 支持主流數(shù)據(jù)庫(MySQL、PostgreSQL、SQLite、Oracle 等);
  • 編譯期代碼生成,無運行時開銷;
  • 支持事務(wù)、關(guān)聯(lián)映射(一對一、一對多)、繼承映射等高級特性;
  • 輕量級,僅需鏈接 ODB 庫,無額外依賴。

2. 環(huán)境搭建

(1)安裝 ODB 工具鏈

  • 下載 ODB 編譯器:從Code Synthesis 官網(wǎng)下載對應(yīng)平臺的 ODB 編譯器(odb命令行工具);
  • 安裝數(shù)據(jù)庫驅(qū)動:如 MySQL 需安裝libmysqlclient,PostgreSQL 需安裝libpq
  • 配置 C++ 編譯環(huán)境:確保編譯器支持 C++11 及以上(如 GCC、Clang、MSVC)。

(2)項目依賴

  • 鏈接 ODB 核心庫(odb)和對應(yīng)數(shù)據(jù)庫驅(qū)動庫(如odb-mysql、odb-sqlite);
  • 包含 ODB 頭文件路徑(#include <odb/database.hxx>等)。

二、ODB 入門:簡單對象映射

1. 定義持久化類

首先定義一個 C++ 類,通過 ODB 注解標記為 “持久化類”,并指定表名、字段屬性:

// person.hxx
#include <string>
#include <odb/core.hxx> // ODB核心頭文件
// 標記為持久化類,對應(yīng)數(shù)據(jù)庫表"person"
#pragma db object table("person")
class Person
{
public:
    Person() {} // 必須提供默認構(gòu)造函數(shù)
    Person(const std::string& name, int age, const std::string& email)
        : name_(name), age_(age), email_(email) {}
    // 訪問器方法
    const std::string& name() const { return name_; }
    int age() const { return age_; }
    const std::string& email() const { return email_; }
private:
    // 主鍵(auto表示自增)
    #pragma db id auto
    unsigned long id_;
    // 普通字段(可指定列名、約束,如not_null)
    #pragma db column("name") not_null
    std::string name_;
    #pragma db column("age")
    int age_;
    #pragma db column("email") unique // 唯一約束
    std::string email_;
    // ODB需要訪問私有成員,聲明友元
    friend class odb::access;
};

2. 生成數(shù)據(jù)庫訪問代碼

ODB 通過編譯器(odb命令)分析注解,生成持久化類的數(shù)據(jù)庫操作代碼:

# 針對MySQL生成代碼,輸出person-odb.hxx和person-odb.cxx
odb -d mysql --generate-query --generate-schema person.hxx
  • -d mysql:指定數(shù)據(jù)庫類型(可選sqlitepgsql等);
  • --generate-query:生成查詢支持代碼;
  • --generate-schema:生成建表 SQL 語句。

3. 基礎(chǔ)數(shù)據(jù)庫操作(CRUD)

(1)初始化數(shù)據(jù)庫連接

#include <odb/database.hxx>
#include <odb/mysql/database.hxx> // MySQL驅(qū)動
// 創(chuàng)建數(shù)據(jù)庫連接(MySQL示例)
std::unique_ptr<odb::database> db(
    new odb::mysql::database(
        "root",      // 用戶名
        "password",  // 密碼
        "test_db",   // 數(shù)據(jù)庫名
        "localhost", // 主機
        3306         // 端口
    )
);

(2)插入數(shù)據(jù)(Create)

#include "person-odb.hxx" // 生成的代碼
Person p("Alice", 25, "alice@example.com");
odb::transaction t(db->begin()); // 開啟事務(wù)
db->persist(p); // 插入對象到數(shù)據(jù)庫
t.commit();     // 提交事務(wù)

(3)查詢數(shù)據(jù)(Read)

主鍵查詢

odb::transaction t(db->begin());
std::shared_ptr<Person> p = db->load<Person>(1); // 根據(jù)主鍵1查詢
std::cout << "Name: " << p->name() << ", Age: " << p->age() << std::endl;
t.commit();

條件查詢

#include <odb/query.hxx>
#include <odb/session.hxx>
odb::session s; // 查詢需開啟session
odb::transaction t(db->begin());
// 構(gòu)建查詢:age > 20 且 name LIKE 'A%'
odb::query<Person> q(
    odb::query<Person>::age > 20 &&
    odb::query<Person>::name.like("A%")
);
// 執(zhí)行查詢并遍歷結(jié)果
for (auto& p : db->query<Person>(q))
    std::cout << p.name() << ": " << p.email() << std::endl;
t.commit();

(4)更新數(shù)據(jù)(Update)

odb::transaction t(db->begin());
std::shared_ptr<Person> p = db->load<Person>(1);
p->age_ = 26; // 修改對象(需將age_改為public或提供setter)
db->update(*p); // 更新數(shù)據(jù)庫
t.commit();

(5)刪除數(shù)據(jù)(Delete)

odb::transaction t(db->begin());
db->erase<Person>(1); // 根據(jù)主鍵刪除
t.commit();

三、ODB 進階特性

1. 關(guān)聯(lián)映射

(1)一對一關(guān)聯(lián)(One-to-One)

例如Person關(guān)聯(lián)Address

// address.hxx
#pragma db object
class Address
{
    // ... 字段定義(主鍵id_,street_,city_等)
};
// person.hxx中添加關(guān)聯(lián)
#pragma db object
class Person
{
    // ... 其他字段
    #pragma db one_to_one // 一對一關(guān)聯(lián)
    odb::lazy_ptr<Address> address_; // 懶加載(訪問時才查詢)
};

(2)一對多關(guān)聯(lián)(One-to-Many)

例如Department包含多個Employee

// employee.hxx
#pragma db object
class Employee
{
    // ... 字段
    #pragma db many_to_one // 多對一(反向關(guān)聯(lián))
    odb::ptr<Department> dept_;
};
// department.hxx
#pragma db object
class Department
{
    // ... 字段
    #pragma db one_to_many(mapped_by = "dept_") // 一對多,指定反向關(guān)聯(lián)字段
    std::vector<odb::ptr<Employee>> employees_;
};

2. 繼承映射

ODB 支持類繼承的表映射,分為三種策略:

  • 單表策略:所有子類映射到同一張表(通過discriminator區(qū)分);
  • Joined 策略:父類和子類分別映射到不同表,查詢時關(guān)聯(lián);
  • Table-per-class 策略:每個子類映射到獨立表。

示例(單表策略):

#pragma db object abstract // 抽象父類
class User
{
    #pragma db id auto
    unsigned long id_;
    std::string username_;
};
#pragma db object
class AdminUser : public User
{
    std::string role_;
};
#pragma db object
class NormalUser : public User
{
    std::string avatar_;
};

3. 事務(wù)與并發(fā)

ODB 支持事務(wù)的 ACID 特性,可通過odb::transaction控制:

odb::transaction t(db->begin());
try
{
    // 批量操作
    db->persist(p1);
    db->persist(p2);
    t.commit();
}
catch (const odb::exception& e)
{
    t.rollback(); // 異常時回滾
    std::cerr << "Transaction failed: " << e.what() << std::endl;
}

四、實戰(zhàn)案例:用戶管理系統(tǒng)

1. 需求分析

實現(xiàn)一個簡單的用戶管理系統(tǒng),支持用戶的增刪改查、角色關(guān)聯(lián)(用戶 - 角色一對多)。

2. 核心代碼實現(xiàn)

(1)定義持久化類

// role.hxx
#pragma db object
class Role
{
public:
    Role(const std::string& name) : name_(name) {}
private:
    friend class odb::access;
    Role() {}
    #pragma db id auto
    unsigned long id_;
    #pragma db not_null unique
    std::string name_; // 角色名:admin, user
};
// user.hxx
#pragma db object
class User
{
public:
    User(const std::string& name, int age) : name_(name), age_(age) {}
private:
    friend class odb::access;
    User() {}
    #pragma db id auto
    unsigned long id_;
    #pragma db not_null
    std::string name_;
    int age_;
    #pragma db many_to_many // 多對多關(guān)聯(lián)角色
    std::vector<odb::ptr<Role>> roles_;
};

(2)生成代碼并編譯

odb -d sqlite --generate-query --generate-schema role.hxx user.hxx
g++ -c user-odb.cxx role-odb.cxx main.cxx -I/path/to/odb/include -L/path/to/odb/lib -lodb -lodb-sqlite

(3)業(yè)務(wù)邏輯實現(xiàn)

#include <odb/sqlite/database.hxx>
#include "user-odb.hxx"
#include "role-odb.hxx"
int main()
{
    // SQLite數(shù)據(jù)庫(文件test.db)
    std::unique_ptr<odb::database> db(new odb::sqlite::database("test.db"));
    // 1. 創(chuàng)建角色
    odb::transaction t1(db->begin());
    db->persist(Role("admin"));
    db->persist(Role("user"));
    t1.commit();
    // 2. 創(chuàng)建用戶并關(guān)聯(lián)角色
    odb::transaction t2(db->begin());
    auto admin_role = db->query_one<Role>(odb::query<Role>::name == "admin");
    User u("Bob", 30);
    u.roles_.push_back(admin_role);
    db->persist(u);
    t2.commit();
    // 3. 查詢用戶及其角色
    odb::session s;
    odb::transaction t3(db->begin());
    auto user = db->load<User>(1);
    std::cout << "User: " << user->name_ << ", Roles: ";
    for (auto& r : user->roles_)
        std::cout << r->name_ << " ";
    t3.commit();
    return 0;
}

五、ODB 最佳實踐與注意事項

  1. 避免過度封裝:簡單查詢直接使用 ODB 的query接口,復(fù)雜 SQL 可通過odb::queryraw()方法嵌入原生 SQL;
  2. 懶加載優(yōu)化:關(guān)聯(lián)對象默認懶加載,批量查詢時可通過odb::join主動關(guān)聯(lián),減少數(shù)據(jù)庫請求;
  3. 性能考量:編譯期生成代碼無運行時開銷,但頻繁的對象持久化需注意事務(wù)批量處理;
  4. 數(shù)據(jù)庫遷移:使用--generate-schema生成的 SQL 文件管理表結(jié)構(gòu),配合版本控制實現(xiàn)遷移;
  5. 異常處理:捕獲odb::exception及其子類(如odb::sql_exception),處理數(shù)據(jù)庫錯誤。

六、總結(jié)

ODB 作為 C++ 的高效 ORM 框架,通過編譯期代碼生成實現(xiàn)了對象與數(shù)據(jù)庫的無縫映射,既保留了 C++ 的性能優(yōu)勢,又簡化了數(shù)據(jù)庫操作。從簡單的 CRUD 到復(fù)雜的關(guān)聯(lián)映射、事務(wù)管理,ODB 都能提供優(yōu)雅的解決方案,是 C++ 后端開發(fā)中替代原生 SQL 的理想選擇。掌握 ODB 的核心用法,可大幅提升項目的開發(fā)效率和可維護性。

到此這篇關(guān)于C++ ODB ORM 從入門到實戰(zhàn)應(yīng)用的文章就介紹到這了,更多相關(guān)C++ ODB ORM 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言之qsort函數(shù)詳解

    C語言之qsort函數(shù)詳解

    這篇文章主要介紹了C語言中qsort函數(shù)的用法實例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C++數(shù)據(jù)結(jié)構(gòu)之AVL樹的實現(xiàn)

    C++數(shù)據(jù)結(jié)構(gòu)之AVL樹的實現(xiàn)

    AVL樹是高度平衡的而二叉樹,它的特點是AVL樹中任何節(jié)點的兩個子樹的高度最大差別為1,本文主要給大家介紹了C++如何實現(xiàn)AVL樹,需要的朋友可以參考下
    2022-06-06
  • C語言數(shù)組應(yīng)用實現(xiàn)三子棋游戲

    C語言數(shù)組應(yīng)用實現(xiàn)三子棋游戲

    這篇文章主要為大家詳細介紹了C語言數(shù)組應(yīng)用實現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 淺談C++性能榨汁機之偽共享

    淺談C++性能榨汁機之偽共享

    使給定內(nèi)存位置被一個線程所訪問,可能還是會有乒乓緩存的存在,是因為另一種叫做偽共享(false sharing)的效應(yīng)。即使數(shù)據(jù)存儲在緩存行中,多個線程對數(shù)據(jù)中的成員進行訪問時,硬件緩存還是會產(chǎn)生乒乓緩存。本文將介紹C++中的偽共享
    2021-06-06
  • C++性能剖析教程之switch語句

    C++性能剖析教程之switch語句

    除了用嵌套if語句外,C++中還提供switch語句,又稱為“開關(guān)語句”,用來實現(xiàn)多分支(多選一),下面這篇文章主要給大家介紹了關(guān)于C++性能剖析教程之switch語句的相關(guān)資料,需要的朋友可以參考下
    2018-06-06
  • 在Qt中使用OpenGL繪制三角形指南

    在Qt中使用OpenGL繪制三角形指南

    在高性能渲染場景中,CPU資源常被過度消耗,導(dǎo)致界面卡頓,而OpenGL作為業(yè)界標準的圖形API,能通過GPU硬件加速顯著降低CPU負載,本文將以繪制三角形為例,教你如何通過Qt的QOpenGLWidget和QOpenGLFunctions實現(xiàn)跨平臺GPU渲染,感興趣的朋友一起看看吧
    2025-04-04
  • C語言函數(shù)聲明以及函數(shù)原型超詳細講解示例

    C語言函數(shù)聲明以及函數(shù)原型超詳細講解示例

    這篇文章主要介紹了C語言函數(shù)聲明以及函數(shù)原型超詳細講解,C語言代碼由上到下依次執(zhí)行,原則上函數(shù)定義要出現(xiàn)在函數(shù)調(diào)用之前,否則就會報錯。但在實際開發(fā)中,經(jīng)常會在函數(shù)定義之前使用它們,這個時候就需要提前聲明
    2023-02-02
  • 最新C語言自定義類型詳解

    最新C語言自定義類型詳解

    生活當中有很多物品是不能簡單的用整型、浮點型、字符型來區(qū)分,它們常常是復(fù)雜的集合,比如人,一個人擁有年齡,身高、體重、學(xué)歷......等信息,我們可以用結(jié)構(gòu)體來實現(xiàn)準確描述人這種復(fù)雜集合,這篇文章主要介紹了C語言?自定義類型,需要的朋友可以參考下
    2023-01-01
  • C++小游戲tankwar之界面繪制的詳細過程

    C++小游戲tankwar之界面繪制的詳細過程

    最近沒有項目做,空閑了下來,于是寫了個c++小游戲來打發(fā)時間,下面通過本文基于圖文并茂的形式給大家介紹C++小游戲tankwar之界面繪制的詳細過程,感興趣的朋友一起看看吧
    2021-05-05
  • C語言實現(xiàn)的學(xué)生選課系統(tǒng)代碼分享

    C語言實現(xiàn)的學(xué)生選課系統(tǒng)代碼分享

    這篇文章主要介紹了C語言實現(xiàn)的學(xué)生選課系統(tǒng)代碼分享,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10

最新評論

玉树县| 巴林右旗| 高陵县| 裕民县| 德清县| 巨鹿县| 姜堰市| 保德县| 谢通门县| 嘉黎县| 措美县| 阿合奇县| 博湖县| 嘉黎县| 夏邑县| 循化| 新津县| 漳平市| 棋牌| 张家港市| 霍林郭勒市| 江安县| 青阳县| 谢通门县| 长宁区| 宜昌市| 云南省| 山阴县| 惠安县| 广德县| 五常市| 宣城市| 义乌市| 勃利县| 包头市| 隆化县| 积石山| 台江县| 兴仁县| 沧州市| 扶绥县|