其實相信每個和mysql打過交道的程序員都應該會嘗試去封裝一套mysql的接口,這一次的封裝已經記不清是我第幾次了,但是每一次我希望都能做的比上次更好,更容易使用。
先來說一下這次的封裝,遵守了幾個原則,其中部分思想是從python借鑒過來的:
1.簡單
簡單,意味著不為了微小的效率提升,而去把接口搞的復雜。因為本身數據庫存儲效率的瓶頸并不是那一兩次內存copy,代碼中隨處可以看到以這個為依據的設計。
2.低學習成本
使用一套新庫通常意味著投入學習成本,而這次的封裝并沒有像django那樣實現一套完整的模型系統,也沒有做soci那樣的語法分析器,我選擇最簡單易懂的方式:做sql語句拼接器,所以對習慣了使用原生mysql api的朋友,學習成本很低
3.模塊化
代碼實際包括了兩個模塊,一個是mysql client端的封裝,一個是sql的拼接器,這兩個模塊是完全獨立的,調用者可以任意組合或者獨立使用。
4.盡量使用STL以及模板,簡化代碼編寫
最大的特點就是大量使用了stringstream進行類型轉化,減少了大量的重復代碼。
OK,基于以上的簡單介紹,我們先來看一下
一.mysql client端的封裝:
class CMYSQLWrapper{ /** * @brief 獲取錯誤信息 * * @return 錯誤信息 */ char* GetErrMsg(); /** * @brief 連接MYSQL,已經支持了自動重連模式,即mysql server關閉鏈接會自動重連 * * @param ip IP * @param user 用戶名 * @param pwd 密碼(沒有則傳NULL) * @param db 庫(沒有則傳NULL) * * @return 0 succ * else fail */ int Open(const char* ip,const char* user,const char* pwd,const char* strDb); /** * @brief 關閉鏈接并釋放result */ void Close(); /** * @brief 執行SQL語句 * * @param strSql 執行語句 * @param result 執行結果 * * @return 0 succ * else fail */ int Query(const char* strSql); /** * @brief 針對Read(select)相關的的Query,可以支持blob了 * * @param strSql sql語句 * @param vecData rows * * @return 0 succ * else fail */ int Query(const char* strSql, vector<map<string, MYSQLValue> > &vecData); /** * @brief 針對Write(insert,update,delete)相關的Query * * @param strSql sql語句 * @param affectRowsCount 影響的行的個數 * * @return 0 succ * else fail */ int Query(const char* strSql, int& affectRowsCount); /** * @brief Select時獲取數據,記得手工析構,或者用StMYSQLRes * * @param result 執行結果 * * @return 0 succ * else fail */ int Result(MYSQL_RES *&result); /** * @brief 返回影響行數 * * @return >0 succ * 0 沒有更新 * <0 fail */ int AffectedRows(); /** * @brief 主要是將blob轉成字符串 * * @param src blob源 * @param len 長度 * * @return 轉化后的字符串 */ string EscStr(const char* src,uint32_t len); /** * @brief 將字符串中的某些字符轉化(如') * * @param src 字符串 * * @return 轉化后的字符串 */ string EscStr(const char* src);}; class CMYSQLWrapper{ /** * @brief 獲取錯誤信息 * * @return 錯誤信息 */ char* GetErrMsg(); /** * @brief 連接MYSQL,已經支持了自動重連模式,即mysql server關閉鏈接會自動重連 * * @param ip IP * @param user 用戶名 * @param pwd 密碼(沒有則傳NULL) * @param db 庫(沒有則傳NULL) * * @return 0 succ * else fail */ int Open(const char* ip,const char* user,const char* pwd,const char* strDb); /** * @brief 關閉鏈接并釋放result */ void Close(); /** * @brief 執行SQL語句 * * @param strSql 執行語句 * @param result 執行結果 * * @return 0 succ * else fail */ int Query(const char* strSql); /** * @brief 針對Read(select)相關的的Query,可以支持blob了 * * @param strSql sql語句 * @param vecData rows * * @return 0 succ * else fail */ int Query(const char* strSql, vector<map<string, MYSQLValue> > &vecData); /** * @brief 針對Write(insert,update,delete)相關的Query * * @param strSql sql語句 * @param affectRowsCount 影響的行的個數 * * @return 0 succ * else fail */ int Query(const char* strSql, int& affectRowsCount); /** * @brief Select時獲取數據,記得手工析構,或者用StMYSQLRes * * @param result 執行結果 * * @return 0 succ * else fail */ int Result(MYSQL_RES *&result); /** * @brief 返回影響行數 * * @return >0 succ * 0 沒有更新 * <0 fail */ int AffectedRows(); /** * @brief 主要是將blob轉成字符串 * * @param src blob源 * @param len 長度 * * @return 轉化后的字符串 */ string EscStr(const char* src,uint32_t len); /** * @brief 將字符串中的某些字符轉化(如') * * @param src 字符串 * * @return 轉化后的字符串 */ string EscStr(const char* src);};
新聞熱點
疑難解答