ORM++ 封裝實戰指南:安全高效的 C++ MySQL 數據庫操作

ORM++ 封裝實戰指南:安全高效的 C++ MySQL 數據庫操作

一、環境準備

1.1 依賴安裝

# Ubuntu/Debian
sudo apt-get install libmysqlclient-dev
# CentOS
sudo yum install mysql-devel# 編譯時鏈接庫 (-I 指定頭文件路徑 -L 指定庫路徑)
g++ main.cpp -std=c++17 -I/usr/include/mysql -lmysqlclient -lpthread

1.2 ORM++ 集成

// 下載頭文件版 ORM++
#include <ormpp/mysql.hpp>
#include <ormpp/dbng.hpp>

二、模型定義規范

2.1 數據表映射

#pragma once
#include <string>
#include <ormpp/ormpp.hpp>struct User {int id;        // 必須包含主鍵字段std::string username;std::string email;time_t create_time;
};
REFLECTION(User, id, username, email, create_time);// 帶注釋的進階版
struct Article {int article_id;  // 主鍵std::string title;std::string content;int author_id;   // 外鍵ormpp::date create_date;
};
REFLECTION_WITH_NAME(Article, "articles", ormpp::field_constraint{&Article::article_id, "PRIMARY KEY AUTO_INCREMENT"},ormpp::field_constraint{&Article::title, "VARCHAR(255) NOT NULL"},ormpp::field_constraint{&Article::author_id, "REFERENCES users(id)"}
);

三、核心封裝類設計

3.1 數據庫管理器

class DatabaseManager {
public:// 單例模式獲取實例static DatabaseManager& Instance() {static DatabaseManager instance;return instance;}// 初始化連接池bool Initialize(const std::string& host,const std::string& user,const std::string& password,const std::string& db,int port = 3306,int poolSize = 5);// 獲取連接(RAII 管理)ormpp::dbng<ormpp::mysql> GetConnection();// CRUD 操作封裝template <typename T, typename... WhereArgs>std::vector<T> Query(const std::string& condition = "", WhereArgs&&... args);template <typename T>int Insert(const T& entity);template <typename T, typename... UpdateArgs>int Update(const T& entity, const std::string& condition, UpdateArgs&&... args);template <typename... DeleteArgs>int Delete(const std::string& condition, DeleteArgs&&... args);private:std::queue<ormpp::dbng<ormpp::mysql>> connectionPool_;std::mutex poolMutex_;std::condition_variable poolCV_;
};

四、CRUD 高級封裝

4.1 安全查詢

template <typename T, typename... Args>
std::vector<T> DatabaseManager::Query(const std::string& condition, Args&&... args) {auto conn = GetConnection();try {// 自動生成 SELECT 語句std::string sql = ormpp::generate_query_sql<T>(condition);// 執行參數化查詢auto result = conn->template query<T>(sql, std::forward<Args>(args)...);ZRY_LOG_DEBUG("Query returned {} records", result.size());return result;} catch (const std::exception& e) {ZRY_LOG_ERROR("Query failed: {}", e.what());throw;}
}// 使用示例
auto users = DatabaseManager::Instance().Query<User>("WHERE age > ?", 18);

4.2 智能插入

template <typename T>
int DatabaseManager::Insert(const T& entity) {auto conn = GetConnection();try {int affected = conn->insert(entity);if (affected > 0) {ZRY_LOG_INFO("Inserted {} successfully", typeid(T).name());}return affected;} catch (const ormpp::mysql_exception& e) {ZRY_LOG_ERROR("Insert failed: {}", e.what());return -1;}
}// 支持批量插入
template <>
int DatabaseManager::Insert<std::vector<User>>(const std::vector<User>& users) {// ... 批量插入優化實現
}

五、事務管理

5.1 事務封裝類

class Transaction {
public:explicit Transaction(DatabaseManager& dbMgr) : dbMgr_(dbMgr), conn_(dbMgr.GetConnection()) {conn_->execute("START TRANSACTION");}~Transaction() {if (!committed_) {conn_->execute("ROLLBACK");}}bool Commit() {try {conn_->execute("COMMIT");committed_ = true;return true;} catch (...) {return false;}}private:DatabaseManager& dbMgr_;ormpp::dbng<ormpp::mysql> conn_;bool committed_ = false;
};// 使用示例
try {Transaction trans(DatabaseManager::Instance());// 執行多個操作trans.Commit();
} catch (...) {// 自動回滾
}

六、查詢構建器

6.1 鏈式調用封裝

class QueryBuilder {
public:QueryBuilder& Where(const std::string& condition) {whereClause_ = "WHERE " + condition;return *this;}QueryBuilder& OrderBy(const std::string& field, bool asc = true) {orderByClause_ = "ORDER BY " + field + (asc ? " ASC" : " DESC");return *this;}QueryBuilder& Limit(int count, int offset = 0) {limitClause_ = "LIMIT " + std::to_string(offset) + "," + std::to_string(count);return *this;}template <typename T>std::vector<T> Execute() {std::string sql = ormpp::generate_query_sql<T>("")+ " " + whereClause_+ " " + orderByClause_+ " " + limitClause_;return DatabaseManager::Instance().Query<T>(sql);}private:std::string whereClause_;std::string orderByClause_;std::string limitClause_;
};// 使用示例
auto users = QueryBuilder().Where("age > ? AND status = ?").OrderBy("create_time", false).Limit(10).Execute<User>();

七、性能優化

7.1 連接池實現要點

bool DatabaseManager::Initialize(...) {for (int i = 0; i < poolSize; ++i) {auto conn = std::make_shared<ormpp::dbng<ormpp::mysql>>();if (conn->connect(host, user, password, db, port)) {connectionPool_.push(conn);}}return !connectionPool_.empty();
}ormpp::dbng<ormpp::mysql> DatabaseManager::GetConnection() {std::unique_lock<std::mutex> lock(poolMutex_);poolCV_.wait(lock, [this]{ return !connectionPool_.empty(); });auto conn = connectionPool_.front();connectionPool_.pop();return conn;
}void ReleaseConnection(ormpp::dbng<ormpp::mysql> conn) {std::lock_guard<std::mutex> lock(poolMutex_);connectionPool_.push(conn);poolCV_.notify_one();
}

八、日志與監控

8.1 SQL 執行日志

// 在查詢執行前記錄
ZRY_LOG_DEBUG("Executing SQL: {}", sql);// 執行后統計耗時
auto start = std::chrono::steady_clock::now();
// ... execute query ...
auto end = std::chrono::steady_clock::now();
ZRY_LOG_PERF("Query took {}ms", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count());

九、最佳實踐

  1. ?參數化查詢?:始終使用 ? 占位符,防止 SQL 注入
db.Query<User>("WHERE username = ?", "john_doe");
  1. ?類型安全?:利用 ORM 的自動類型轉換
auto products = db.Query<Product>("WHERE price > ?", 100.0f);
  1. ?連接生命周期?:使用 RAII 管理連接
{auto conn = db.GetConnection();// 使用連接...
} // 自動釋放回連接池
  1. ?錯誤處理?:統一異常捕獲策略
try {// 數據庫操作
} catch (const ormpp::mysql_exception& e) {// 處理數據庫特定錯誤
} catch (const std::exception& e) {// 處理通用錯誤
}

十、擴展方向

  1. ?異步操作?:結合 libuv 或 Boost.Asio 實現異步查詢
  2. ?二級緩存?:集成 Redis 緩存高頻查詢結果
  3. ?數據分片?:實現跨多個數據庫實例的 Sharding
  4. ?健康檢查?:定期驗證連接有效性
  5. ?SQL 分析?:記錄慢查詢日志,優化索引

通過以上封裝,開發者可以:
? 減少 70% 以上的樣板代碼
? 提升 SQL 注入防護等級
? 統一管理數據庫訪問策略
? 方便進行性能監控和優化
? 快速適應數據庫 schema 變更

完整示例代碼參見:[GitHub 倉庫鏈接]

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/84541.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/84541.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/84541.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JESD204B 協議介紹

一、協議概述 JESD204B是由JEDEC&#xff08;固態技術協會&#xff09;制定的高速串行接口標準&#xff0c;專為模數轉換器&#xff08;ADC&#xff09;、數模轉換器&#xff08;DAC&#xff09;與邏輯器件&#xff08;如FPGA、ASIC&#xff09;之間的數據傳輸設計。其核心目標…

yolov8,c++案例匯總

文章目錄 引言多目標追蹤案例人體姿態估計算法手勢姿態估計算法目標分割算法 引言 以下案例,基于c,ncnn,yolov8既可以在windows10/11上部署, 也可以在安卓端部署, 也可以在嵌入式端部署, 服務器端可支持部署封裝為DLL,支持c/c#/java端調用 多目標追蹤案例 基于yolov8, ncnn,…

運動規劃實戰案例 | 圖解基于狀態晶格(State Lattice)的路徑規劃(附ROS C++/Python仿真)

目錄 1 控制采樣 vs 狀態采樣2 State Lattice路徑規劃2.1 算法流程2.2 Lattice運動基元生成2.3 幾何代價函數2.4 運動學約束啟發式 3 算法仿真3.1 ROS C仿真3.2 Python仿真 1 控制采樣 vs 狀態采樣 控制采樣的技術路線源自經典的運動學建模思想。這種方法將機器人的控制指令空…

BERT框架:自然語言處理的革命性突破

引言 在自然語言處理&#xff08;NLP&#xff09;領域&#xff0c;2018年Google推出的BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;框架無疑是一場革命。作為基于Transformer架構的雙向編碼器表示模型&#xff0c;BERT通過預訓練學習…

【Fifty Project - D31】

結束了一個超級消耗周末&#xff0c;滿安排之健身梅溪湖游泳做飯喝酒羽毛球賽 完全力竭了&#xff0c;久久不能恢復過來&#xff0c;暫停健身安排了 端午后再繼續 今日完成記錄 TimePlan完成情況7&#xff1a;30 - 8&#xff1a;10有氧爬坡√9&#xff1a;00 - 11&#xff1a;…

信息學奧賽一本通 1547:【 例 1】區間和

【題目鏈接】 ybt 1547&#xff1a;【 例 1】區間和 【題目考點】 1. 線段樹 2. 樹狀數組 【解題思路】 本題要求維護區間和&#xff0c;實現單點修改、區間查詢。 解法1&#xff1a;線段樹 線段樹原理&#xff0c;及實現方法見&#xff1a;洛谷 P3374 【模板】樹狀數組…

力扣面試150題--求根節點到葉節點數字之和

Day 48 題目描述 思路 我們利用sum這個全局變量來保存總和值&#xff0c;遞歸函數sum來計算每個根到葉子節點路徑所代表的數&#xff0c;由于我們需要遍歷到每條根到葉子節點的路徑&#xff0c;所有我采取了前序遍歷&#xff0c;如果不是葉子節點&#xff0c;就計算到該節點代…

DJI上云API官方demo學習

1、websocket&#xff0c;所在位置如下圖&#xff0c;調用的可以用//websocket搜索 2、用到的http客戶端&#xff0c;axios 3、很多和后端交互都是走的http請求

uniapp開發小程序,如何根據權限動態配置按鈕或頁面內容

前言 寫了好幾個項目&#xff0c;發現小程序對權限控制非常麻煩&#xff0c;于是有了這個想法&#xff0c;但是網上找了一圈沒有一個比較完善的講解&#xff0c;因為小程序不支持自定義指令&#xff0c;所以不能像后臺那樣方便&#xff0c;于是就將幾個博主的想法結合。 思路就…

LSTM+Transformer混合模型架構文檔

LSTMTransformer混合模型架構文檔 模型概述 本項目實現了一個LSTMTransformer混合模型&#xff0c;用于超臨界機組協調控制系統的數據驅動建模。該模型結合了LSTM的時序建模能力和Transformer的自注意力機制&#xff0c;能夠有效捕捉時間序列數據中的長期依賴關系和變量間的復…

測量尺子:多功能測量工具,科技改變生活

測量尺子是一款專業的測距儀測量萬能工具箱類型手機APP&#xff0c;旨在為用戶提供最貼心的測量助手。它擁有和現實測量儀器一樣的測量標準&#xff0c;更簡單便捷且精準的測量方式&#xff0c;最新AR科技測量更是大大拓寬了可以被測量的高度和深度。無論是日常使用、學習還是工…

結課作業01. 用戶空間 MPU6050 體感鼠標驅動程序

目錄 一. qt界面實現 二. 虛擬設備模擬模擬鼠標實現體感鼠標 2.1 函數聲明 2.2 虛擬鼠標實現 2.2.1 虛擬鼠標創建函數 2.2.2 鼠標移動函數 2.2.3 鼠標點擊函數 2.3 mpu6050相關函數實現 2.3.1 i2c設備初始化 2.3.2 mpu6050寄存器寫入 2.3.3 mpu6050寄存器讀取 2.3.…

深入淺出 Python Testcontainers:用容器優雅地編寫集成測試

在現代軟件開發中&#xff0c;自動化測試已成為敏捷開發與持續集成中的關鍵環節。單元測試可以快速驗證函數或類的行為是否符合預期&#xff0c;而集成測試則確保多個模塊協同工作時依然正確。問題是&#xff1a;如何讓集成測試可靠、可重復且易于維護&#xff1f; 這時&#…

JVM 的垃圾回收器

新生代回收器 通性 會觸發StW&#xff0c;暫停所有應用線程復制算法 Serial 單線程回收適合單線程系統 ParNew 多線程回收優先保證響應速度&#xff0c;降低 STW&#xff08;STW 越大&#xff0c;執行垃圾回收的時間越長&#xff0c;回收的垃圾越多&#xff0c;減少垃圾回…

【筆記】排查并解決Error in LLM call after 3 attempts: (status code: 502)

#工作記錄 一、問題描述 在部署運行部署對沖基金分析工具 ai-hedge-fund 時&#xff0c;不斷出現以下報錯&#xff0c;導致項目運行異常&#xff1a; Error in LLM call after 3 attempts: (status code: 502) Error in LLM call after 3 attempts: [WinError 10054] 遠程主…

GO 語言進階之 Template 模板使用

更多個人筆記見&#xff1a; github個人筆記倉庫 gitee 個人筆記倉庫 個人學習&#xff0c;學習過程中還會不斷補充&#xff5e; &#xff08;后續會更新在github上&#xff09; 文章目錄 Template 模板基本示例語法1. 基本輸出語法2. 控制結構3. 空白字符控制4. Must函數 Temp…

origin繪圖之【如何將多條重疊、高度重疊的點線圖、折線圖分開】

在日常的數據可視化工作中&#xff0c;Origin 作為一款功能強大的科研繪圖軟件&#xff0c;廣泛應用于實驗數據處理、結果展示與論文圖表制作等領域。然而&#xff0c;在處理多組數據、特別是繪制多條曲線的折線圖或點線圖時&#xff0c;常常會遇到這樣一個困擾&#xff1a;多條…

Java基礎 Day19

一、泛型&#xff08;JDK5引入&#xff09; 1、基本概念 在編譯階段約束操作的數據類型&#xff0c;并進行檢查 好處&#xff1a;統一數據類型&#xff0c;將運行期的錯誤提升到了編譯期 泛型的默認類型是 Object 2、泛型類 在創建類的時候寫上泛型 在創建具體對象的時候…

Gitlab-Runner安裝

文章目錄 helm方式安裝在K8S上參考gitlab CI/CD 文件變量緩存服務器K8S部署 docker鏡像mavendocker安裝docker buildx minionodehelmkubectlsonar-scanner-cli 問題清除cachehelm執行時無權限 下載鏡像失敗下載gitlab-runner鏡像失敗 Gitlab-ci中使用java前端 helm方式安裝在K8…

在 Ubuntu linux系統中設置時區的方案

查看時區 在 Ubuntu 系統中&#xff0c;可以通過以下方法查看當前時區設置&#xff1a; 1. 使用 timedatectl 命令&#xff08;推薦&#xff09; 在終端運行以下命令&#xff1a; timedatectl輸出示例&#xff1a; Local time: Sun 2025-05-25 10:30:00 CST Universal t…