C++学习记录:C++连接MySql数据库

  之前学习了MySql数据库相关的内容,但是并没有在编写C++代码中用到MySql相关内容。
  本篇笔记记录了个人在 VS2019 中使用 C++ 连接 MySql 数据库的过程。使C++代码中可以实现连接数据库、执行语句、显示查询结果等基础功能。

一、基础准备

1. 在目录中添加路径

  首先找到 MySql 所在的文件夹,其中有includelib文件夹,随后打开VS项目属性页,把include文件夹路径填入 包含目录 内,把 lib 文件夹路径填入 库目录 内。
在这里插入图片描述

在这里插入图片描述

2. 添加依赖项

  在lib文件夹中找到这个libmysql.lib库文件,在VS项目属性页中,把该库文件添加至 附加依赖项 即可。
在这里插入图片描述
在这里插入图片描述

3. 移动DLL文件

  为了使动态库可以正确被使用,我们需要把lib文件夹内的libmysql.dll文件复制到之后编译生成的可执行文件目录下,随后程序方可正常运行。
在这里插入图片描述

※ 注意

  1. 注意自己的 MySQL 版本位数,由此在编译器中选择 32位/64位 编译。
  2. 如果libmysql.dll文件放置的位置不对,会报错找不到libmysql.dll文件。

二、代码相关

0. 基础

1
2
3
4
5
6
7
8
9
10
11
12
MySQL的相关头文件是:
#include<mysql.h>
连接数据库:
mysql_real_connect(...);
执行MySQL语句:
mysql_query(...);
获取上一条MySQL语句执行结果:
mysql_store_result(...);
获取上一条MySQL语句执行结果行数:
mysql_affected_rows(...);

等等...

1. 样例代码

  本测试代码实现了基础的连接数据库、执行数据库语句、输出查询结果等基础功能。

mysql.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef MY_SQL_H
#define MY_SQL_H

#include<iostream>
#include<Windows.h>
#include<WinSock.h>
#include<mysql.h>

class DataBase
{
public:
DataBase();
~DataBase();
//连接数据库 参数为ip 用户名 密码 数据库名 端口
bool Connect(const char* ip, const char* name, const char* cypher, const char* database_name, const int port);
//获取表内的字段数
int GetTableField(const char* table_name);
//查询表 参数为表名
bool Query(const char* table_name);
//自由执行指令
bool Implement(const char* sentence);


private:
bool _state;//连接状态 true为已连接
MYSQL* _mysql;//mysql连接
MYSQL_FIELD* _fd;//字段列数组
char _field[32][32];//存字段名二维数组
MYSQL_RES* _res;//这个结构代表返回行的一个查询结果集
MYSQL_ROW _column;//一个行数据的类型安全(type-safe)的表示,表示数据行的列
char _query[150];//查询语句
};

#endif // !MY_SQL_H

mysql.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "mysql.h"

DataBase::DataBase()
{
_state = false;
_mysql = new MYSQL;
_fd = nullptr;
memset(_field, NULL, sizeof(_field));
_res = nullptr;
_column = nullptr;
memset(_query, NULL, sizeof(_query));
}

DataBase::~DataBase()
{
}

bool DataBase::Connect(const char* ip, const char* name, const char* cypher, const char* database_name, const int port)
{
if (true == _state)
{
printf("Database connected\n");
return false;
}
//初始化mysql
mysql_init(_mysql);
//返回false则连接失败,返回true则连接成功
if (!(mysql_real_connect(_mysql, ip, name, cypher, database_name, port, NULL, 0))) //中间分别是主机,用户名,密码,数据库名,端口号(可以写默认0或者3306等),可以先写成参数再传进去
{
printf("Error connecting to database:%s\n", mysql_error(_mysql));
return false;
}
else
{
_state = true;
printf("Connected succeed\n\n");
return true;
}
return true;
}

int DataBase::GetTableField(const char* table_name)
{
if (false == _state)
{
printf("Database not connected\n");
return -1;
}
//查询内容
sprintf_s(_query, "desc %s", table_name); //desc 语句获取字段数
//设置编码格式(SET NAMES GBK也行),否则cmd下中文乱码
mysql_query(_mysql, "set names gbk");
//返回0 查询成功,返回1查询失败
if (mysql_query(_mysql, _query)) //执行SQL语句
{
printf("Query failed (%s)\n", mysql_error(_mysql));
return false;
}
//获取结果集
if (!(_res = mysql_store_result(_mysql))) //获得sql语句结束后返回的结果集
{
printf("Couldn't get result from %s\n", mysql_error(_mysql));
return false;
}
//数据行数即为字段个数
return mysql_affected_rows(_mysql);
}

bool DataBase::Query(const char* table_name)
{
if (false == _state)
{
printf("Database not connected\n");
return false;
}
//获取字段数
int field = GetTableField(table_name);
//查询内容
sprintf_s(_query, "select * from %s", table_name); //执行查询语句
//设置编码格式(SET NAMES GBK也行),否则cmd下中文乱码
mysql_query(_mysql, "set names gbk");
//返回0 查询成功,返回1查询失败
if (mysql_query(_mysql, _query)) //执行SQL语句
{
printf("Query failed (%s)\n", mysql_error(_mysql));
return false;
}
else
{
printf("query success\n");
}
//获取结果集
if (!(_res = mysql_store_result(_mysql))) //获得sql语句结束后返回的结果集
{
printf("Couldn't get result from %s\n", mysql_error(_mysql));
return false;
}
//打印数据行数
printf("number of dataline returned: %lld\n", mysql_affected_rows(_mysql));
//获取字段的信息
char* str_field[32]; //定义一个字符串数组存储字段信息
for (int i = 0; i < field; i++) //在已知字段数量的情况下获取字段名
{
str_field[i] = mysql_fetch_field(_res)->name;
}
for (int i = 0; i < field; i++) //打印字段
{
printf("%10s\t", str_field[i]);
}
printf("\n");
//打印获取的数据
while (_column = mysql_fetch_row(_res)) //在已知字段数量情况下,获取并打印下一行
{
for (int i = 0; i < field; i++)
{
printf("%10s\t", _column[i]); //column是列数组
}
printf("\n");
}
return true;
}

bool DataBase::Implement(const char* sentence)
{
if (false == _state)
{
printf("Database not connected\n");
return false;
}
//查询内容
sprintf_s(_query, "%s", sentence); //desc 语句获取字段数
//设置编码格式(SET NAMES GBK也行),否则cmd下中文乱码
mysql_query(_mysql, "set names gbk");
//执行SQL语句
if (mysql_query(_mysql, _query))
{
printf("Query failed (%s)\n", mysql_error(_mysql));
return false;
}
return true;
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include"mysql.h"

int main()
{
DataBase* d1 = new DataBase;
//连接
d1->Connect("localhost", "root", "123456", "test", 0);
printf("\n");
//查询表
d1->Query("t_student");
printf("\n");
//添加内容
d1->Implement("insert into t_student values(201916010001, '赵四', '2019-09-09', now())");
printf("\n");
//查询表
d1->Query("t_student");
printf("\n");
return 0;
}

三、GitHub项目

点我跳转github