分享封裝好的非同步Mysql動態庫(DyNetMysql.dll) + 項目源碼

來源:互聯網
上載者:User

標籤:

在做C++項目時,經常會用到Mysql資料庫,Mysql介面提供給我們的資料是相當原始的,如:欄位名、欄位類型,欄位長度等等,一般情況我們都想一種更方便獲得資料

如:

XXXStruct* pRecourdInfo = (const XXXStruct*)(mysql獲得的資料指標);

直接轉換欄位對應的結構來,這樣能大大方便我們使用

這個功能已經在我之前發表上一篇文章<<分享一直在維護簡單實用高效的C++Socket架構Swa-server(開源+源碼)>>中實現,現在是將它封裝成為一個dll

最近有點時間,就學習了dll相關知識,然後將封裝成一個dll,這樣方便使用及移植到其他項目。於是將swa-server中的mysql非同步處理功能代碼分離出來,建立一個DyNetMysql項目,設定為dll項目

關於dll項目及匯出不要這裡講述,園友自己百度查詢(zf把Google封了真是服了)

根據園友性格就先上代碼(*_*)

// TestDll.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include "../../DyNetServer/NetServer.h"#include "../../DyNetMysql/DbSession.h"#include "../../DyNetMysql/DbRecordSet.h"#include <iostream>using namespace std;NetServer*gNetServer;IDbSession*gDataBase;void OnNetMsgEnter( NetSocket& rSocket );void OnNetMsgExit( NetSocket& rSocket );void OnNetMsg( NetSocket& rSocket , NetMsgHead* pHead );#pragma pack(push,1)struct CharacterInfo{int64 type_idx;char nick[32];int32 level;};#pragma pack(pop)void DBCallbase(void* pUser, const void* pMsg){const DbRecordSet* pRecordSet = static_cast<const DbRecordSet*>(pMsg);for (int32 i = 0 ; i < pRecordSet->CountRecord();++i ){const CharacterInfo* pInfo = static_cast<const CharacterInfo*>(pRecordSet->GetRecordBuff(i));printf("id:%ld nick:%s level:%d \n",pInfo->type_idx,pInfo->nick,pInfo->level);}}int _tmain(int argc, _TCHAR* argv[]){// 啟動msyqlgDataBase = DbSessionMgr::Instance()->AddDatabase("127.0.0.1", "root", "root", "swa_data", false);ASSERT(gDataBase);// 初始化Scoket服務gNetServer = NetServerMgr::Instance()->AddNetServer();gNetServer->SetAddress("127.0.0.1", 4321);gNetServer->SetHandler(OnNetMsgEnter, OnNetMsg, OnNetMsgExit);// 啟動Socket服務gNetServer->Start();gDataBase->ExecuteAsyncSQL("SELECT `type_idx`,`nick`,`level` FROM `character`",NULL,DBCallbase);while (true){Sleep(1);NetServerMgr::Instance()->Update(0); //邏輯處理DbSessionMgr::Instance()->Update(0); //SQL處理及回調}return 0;}void OnNetMsgEnter(NetSocket& rSocket){int a = 1;}void OnNetMsg(NetSocket& rSocket, NetMsgHead* pHead){int a = 1;}void OnNetMsgExit(NetSocket& rSocket){int a = 1;}

這裡啟動建立一個Mysql連線物件,如果成功返回!null,然後可以非同步執行sql及設定回調(可以不設定回調)

上述代碼運行如下(為什麼用printf,如果是字元放在第二以上顯示為<null>,園友如果知道是什麼原因,LZ感激不盡):

其實實現將資料直接轉結構體也不是很難,即每行給一個char buffer[65536],然後將mysql的欄位記憶體拷貝進去,之後再轉為結構體即可

這裡需要注意的,如果是char或varchar欄位的,轉出來要知道mysql是用什麼字元編碼,如果是utf-8則它byte最大長度為定義長度*3,本dynetmysql是按utf-8,且長度預設為位元組長度,所以儲存是中文時要注意,一個中文是用3個長度。

相關類部分代碼1:

    DbRecordSet&    m_rRecordSet;    vector<DbField>    m_vecFields;    char            m_arrRowBuff[65536]; // 每一行內容記錄,每個欄位記錄它的開始位置即可,則一行記錄最大為64k     uint32            m_nBuffBegin; // 已經使用的位置

相關類部分代碼2:

    switch (nType)    {    case FIELD_TYPE_TINY:    {        mI64Val = pszValue ? atol(pszValue) : 0;        memcpy(&m_arrRowBuff[m_nBuffBegin], &mI64Val, 1);        m_nBuffBegin += 1;    }        break;    case FIELD_TYPE_SHORT:    {        mI64Val = pszValue ? atol(pszValue) : 0;        memcpy(&m_arrRowBuff[m_nBuffBegin], &mI64Val, 2);        m_nBuffBegin += 2;    }        break;    case FIELD_TYPE_LONG:    {        mI64Val = pszValue ? atol(pszValue) : 0;        memcpy(&m_arrRowBuff[m_nBuffBegin], &mI64Val, 4);        m_nBuffBegin += 4;    }        break;    case FIELD_TYPE_FLOAT:    {        mF64Val = pszValue ? atof(pszValue) : 0;        memcpy(&m_arrRowBuff[m_nBuffBegin], &mF64Val, 4);        m_nBuffBegin += 4;    }        break;    case FIELD_TYPE_LONGLONG:    {        mI64Val = pszValue ? atol(pszValue) : 0;        memcpy(&m_arrRowBuff[m_nBuffBegin], &mI64Val, 8);        m_nBuffBegin += 8;    }        break;    case FIELD_TYPE_DOUBLE:    {        mF64Val = pszValue ? atof(pszValue) : 0;        memcpy(&m_arrRowBuff[m_nBuffBegin], &mF64Val, 8);        m_nBuffBegin += 8;    }        break;    case FIELD_TYPE_STRING:// char    case FIELD_TYPE_VAR_STRING:// var_char    {        memcpy(&m_arrRowBuff[m_nBuffBegin], pszValue, nLen / 3); // mysql char 定義大小會按最大長底去計算長度,這裡限制按位元組大小去截斷        m_nBuffBegin += nLen / 3;    }        break;    case MYSQL_TYPE_TINY_BLOB:    case MYSQL_TYPE_MEDIUM_BLOB:    case MYSQL_TYPE_LONG_BLOB:    case MYSQL_TYPE_BLOB:    {        memcpy(&m_arrRowBuff[m_nBuffBegin], pszValue, nLen);        m_nBuffBegin += nLen;    }        break;

目前這個DyNetMysql.dll還不完善,如果是直接select 則可以建立結構體與它對應則可直接轉結構體,如果是其它如update,delete乖等,則建議設定不使用回調或使用預存程序。

測試代碼中也用到了最近封裝一個非同步Socket的dll,如果大家感興趣,請留言和推薦吧,我才會有動力跟園友一起分享!如果有問題,可以留言或qq296464231問我

項目源碼下載

 

分享封裝好的非同步Mysql動態庫(DyNetMysql.dll) + 項目源碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.