栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Windows 下 使用 MySQL C API 存取 BLOB 数据

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Windows 下 使用 MySQL C API 存取 BLOB 数据

目录

写作背景

内容提要

环境部署

项目配置

1.MySql 部分

2.msgpack 部分

相关代码

1.MySQL 表的设计

2.在 C++ 项目中,使用MySql C API 存取这张表


写作背景

有时候开发中会需要将一些不太基本,不太规范的数据存到数据库。比如不定长的数组,对象,这些内容无法与MySql中的普通字段类型对应上。如果将这些数组,对象中的基本数据类型拆分出来,又需要创建额外的表来存取。为了不创建额外的表 ,将复合型的数据类型和基本数据类型存在同一张表,于是有了这篇文章。

内容提要

1.通过MySql C API,以C++语言对数据库表进行操作

2.使用 msgpack 库对复杂数据,进行序列化/反序列化便于存取 BLOB 类型

环境部署

安装MySql版本:8.0

这部分内容,网络上有很多文章可供参考不再赘述。

项目配置

IDE:Visual Studio 2019,解决方案平台 x64

1.MySql 部分

项目包含目录:mysql安装目录include

项目包含库文件:mysql安装目录lib                //这里我们只需要         libmysql.lib

项目执行程序需要的dll:libmysql.dll                //可放到系统目录下,也可以和可执行程序同一目录

2.msgpack 部分

下载msgpack-c-cpp-4.1.1:C++ msgpack GitHub

项目包含文件:……msgpack-c-cpp-4.1.1include

相关代码

1.MySQL 表的设计
  • 创建一张玩家背包表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_bag
-- ----------------------------
DROp TABLE IF EXISTS `t_bag`;
CREATE TABLE `t_bag`  (
  `uid` bigint(0) NOT NULL COMMENT '玩家唯一标识',
  `fixed_bag` blob NULL COMMENT '玩家的固定背包,容量固定',
  `var_bag` blob NULL COMMENT '玩家的无限背包,容量不固定',
  PRIMARY KEY (`uid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

2.在 C++ 项目中,使用MySql C API 存取这张表
  • 首先是 mysql_tool.h 头文件,对 MySQL C API进行了一些封装处理便于使用

        

#ifndef _MSYQL_TOOL_H
#define _MSYQL_TOOL_H

#include "mysql.h"				//包含这个文件以使用 C API
#include 
#include 
#include 
using namespace std;

//数据库配置,需要修改成自己的
constexpr auto dbip = "127.0.0.1";		//数据库ip	;
constexpr auto dbuser = "root";			//数据库用户
constexpr auto dbpwd = "123456";		//数据库密码
constexpr auto dbname = "test";			//数据库名字

//mysql 执行返回
//插入,查询,存储过程……
struct sReuslt
{
	int rtCode;				//错误码 , 0:成功……
	MYSQL_RES* res;			//结果集

	void afterExecute(std::function func)
	{
		func(res);
	}
};

//将 %s 转为 "%s"
std::string getNewQuery(std::string qry)
{
	std::string new_qry(qry);
	auto offset = 0;
	auto pos = new_qry.find("%s",offset);
	while (pos != std::string::npos)
	{
		new_qry = new_qry.insert(pos + 2, """);
		new_qry = new_qry.insert(pos, """);
		offset = pos + 2;
		pos = new_qry.find("%s", offset);
	}
	return new_qry;
}


//对MySql C API 进行一些封装,便于使用
class mysql_tool
{
private:
	  MYSQL  osql;
	  bool is_init = false;
public:
	void init()
	{
		mysql_init(&osql);
		is_init = true;
	}

	 auto get()
	{
		if (false == is_init)
			init();

		return &osql;
	}

	 void connectMySql()
	{
		if (mysql_real_connect(get(), dbip, dbuser, dbpwd, dbname, 3306, NULL, 0))
			cout << "数据库连接成功!n";
		else
		{
			auto errcode = mysql_errno(get());
			cout <<"error code : "< 
  • 然后就是使用部分了,这里我是用了 main.cpp 源文件

#include 
#include 
#include "mysql.h"
#include 
#include 
#include 
#include "mysql_tool.h"
#define MSGPACK_NO_BOOST		//解决 无法打开包括文件: “boost/predef/other/endian.h”: No such file or directory
#include "msgpack.hpp"
using namespace std;

//用来存储的复合对象
struct item
{
	int id;		//道具id
	int count;	//道具数量
	MSGPACK_DEFINE(id, count);		//启用 msgpack 序列化,反序列化
};

void loadData(item* fixedBag, std::vector& varBag)
{
	fixedBag[0].id = 5;		//为了简便
	fixedBag[0].count = 3;

	fixedBag[1].id = 4;
	fixedBag[1].count = 20;

	for (size_t i = 0; i < 10; ++i)
	{
		item tmp;
		tmp.id = i + 2;
		tmp.count = 22;
		varBag.push_back(tmp);		//10 个道具
	}
}

int main()
{
	mysql_tool sql;
	sql.connectMySql();		//连接数据库
	auto ret = sql.getDBbyName("test");		//选择数据库
	if (0 != ret)
	{
		sql.printError();
		return -1;
	}

	item fixedBag[2] = { 0 };			//固定背包的结构  2 个道具
	std::vector varBag;		//可变背包

	loadData(fixedBag, varBag);		//填充数据

	std::stringstream ss;
	msgpack::pack(ss, fixedBag);		//序列化
	std::string ser_str = ss.str();

	std::stringstream var_bag_ss;
	msgpack::pack(var_bag_ss, varBag);		//序列化操作
	string ser_str_var_bag = var_bag_ss.str();

	//执行插入
	auto rst = sql.execute("INSERT into t_bag (uid, fixed_bag, var_bag) VALUES(%d,%s,%s);", 100011, ser_str.c_str(), ser_str_var_bag.c_str());

	//判断插入结果
	if (0 != rst)
	{
		sql.printError();
	}
	else {
		cout << "insert success!" << endl;
	}


	//查询查询数据库
	string query_str = "select fixed_bag, var_bag from t_bag where uid = %d";
	sql.executeEx(query_str, 100011).afterExecute(
		[=](MYSQL_RES* res) {

			auto row = mysql_fetch_row(res);
			while (row)
			{
				auto one = row[0];
				auto tow = row[1];
				item newFixedBag2[2] = { 0 };
				vector new_var_bag2;

				auto fb_obj_hdl = msgpack::unpack(row[0], strlen(row[0]));
				fb_obj_hdl.get().convert(newFixedBag2);

				auto nvb_obj_hdl = msgpack::unpack(row[1], strlen(row[1]));
				nvb_obj_hdl.get().convert(new_var_bag2);
				//bags* fixedBag = (bags*)one;
				int abc = 1111;

				row = mysql_fetch_row(res);
			}

		});

	system("pause");
	return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1038849.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号