mysql 动态库_分享封装好的异步Mysql动态的库(DyNetMysql.dll) + 项目源码

在做C++项目时,经常会用到Mysql数据库,Mysql接口提供给我们的数据是相当原始的,如:字段名、字段类型,字段长度等等,一般情况我们都想一种更方便获得数据

如:

XXXStruct* pRecourdInfo = (const XXXStruct*)(mysql获得的数据指针);

直接转换字段对应的结构来,这样能大大方便我们使用

最近有点时间,就学习了dll相关知识,然后将封装成一个dll,这样方便使用及移植到其他项目。于是将swa-server中的mysql异步处理功能代码分离出来,创建一个DyNetMysql项目,设置为dll项目

关于dll项目及导出不要这里讲述,园友自己百度查询(zf把谷歌封了真是服了)

根据园友性格就先上代码(*_*)

// TestDll.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include "../../DyNetServer/NetServer.h"

#include "../../DyNetMysql/DbSession.h"

#include "../../DyNetMysql/DbRecordSet.h"

#include

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(pMsg);

for (int32 i = 0 ; i < pRecordSet->CountRecord();++i )

{

const CharacterInfo* pInfo = static_cast(pRecordSet->GetRecordBuff(i));

printf("id:%ld nick:%s level:%d \n",pInfo->type_idx,pInfo->nick,pInfo->level);

}

}

int _tmain(int argc, _TCHAR* argv[])

{

// 启动msyql

gDataBase = 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,如果是字符放在第二以上显示为,园友如果知道是什么原因,LZ感激不尽):

f501c43baa9705f07d0038b36bc35674.png

其实实现将数据直接转结构体也不是很难,即每行给一个char buffer[65536],然后将mysql的字段内存拷贝进去,之后再转为结构体即可

这里需要注意的,如果是char或varchar字段的,转出来要知道mysql是用什么字符编码,如果是utf-8则它byte最大长度为定义长度*3,本dynetmysql是按utf-8,且长度默认为字节长度,所以存储是中文时要注意,一个中文是用3个长度。

相关类部分代码1:

DbRecordSet&m_rRecordSet;

vectorm_vecFields;char m_arrRowBuff[65536]; //每一行内容记录,每个字段记录它的开始位置即可,则一行记录最大为64k

uint32 m_nBuffBegin; //已经使用的位置

相关类部分代码2:

switch(nType)

{caseFIELD_TYPE_TINY:

{

mI64Val= pszValue ? atol(pszValue) : 0;

memcpy(&m_arrRowBuff[m_nBuffBegin], &mI64Val, 1);

m_nBuffBegin+= 1;

}break;caseFIELD_TYPE_SHORT:

{

mI64Val= pszValue ? atol(pszValue) : 0;

memcpy(&m_arrRowBuff[m_nBuffBegin], &mI64Val, 2);

m_nBuffBegin+= 2;

}break;caseFIELD_TYPE_LONG:

{

mI64Val= pszValue ? atol(pszValue) : 0;

memcpy(&m_arrRowBuff[m_nBuffBegin], &mI64Val, 4);

m_nBuffBegin+= 4;

}break;caseFIELD_TYPE_FLOAT:

{

mF64Val= pszValue ? atof(pszValue) : 0;

memcpy(&m_arrRowBuff[m_nBuffBegin], &mF64Val, 4);

m_nBuffBegin+= 4;

}break;caseFIELD_TYPE_LONGLONG:

{

mI64Val= pszValue ? atol(pszValue) : 0;

memcpy(&m_arrRowBuff[m_nBuffBegin], &mI64Val, 8);

m_nBuffBegin+= 8;

}break;caseFIELD_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;caseMYSQL_TYPE_TINY_BLOB:caseMYSQL_TYPE_MEDIUM_BLOB:caseMYSQL_TYPE_LONG_BLOB:caseMYSQL_TYPE_BLOB:

{

memcpy(&m_arrRowBuff[m_nBuffBegin], pszValue, nLen);

m_nBuffBegin+=nLen;

}break;

目前这个DyNetMysql.dll还不完善,如果是直接select 则可以创建结构体与它对应则可直接转结构体,如果是其它如update,delete乖等,则建议设置不使用回调或使用存储过程。

测试代码中也用到了最近封装一个异步Socket的dll,如果大家感兴趣,请留言和推荐吧,我才会有动力跟园友一起分享!如果有问题,可以留言或qq296464231问我

5859b11f36a4e1e36b41004ee911d736.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值