MySQL快速入门——使用C_C++连接
MySQL快速入门——使用C_C++连接
- 1. C 开发包的下载和安装【Ubuntu】
- 2. C++ 开发包下载和安装【Ubuntu】
- 3. 尝试链接mysql client,看看安装是否成功
- 4. C API 接口介绍
- 4.1 基础操作
- 4.2 查看查询结果
- 4.3 综合练习
1. C 开发包的下载和安装【Ubuntu】
1. 检查Connector/C开发包是否存在
- 出现如下情况就是存在了,开发包已经在系统中了,可以直接开始使用了,跳过这一大节(1大节)。
(base) ubuntu@Ubuntu22:~$ dpkg -l | grep mysqlclient
ii libmysqlclient-dev 8.0.43-1ubuntu22.04 amd64 MySQL development headers
ii libmysqlclient21:amd64 8.0.43-1ubuntu22.04 amd64 MySQL shared client libraries
- 我们再来看一看库文件和,头文件:
(base) ubuntu@Ubuntu22:~$ sudo ls /usr/include/mysql/ -l
total 396
-rw-r--r-- 1 root root 5781 7月 9 16:45 errmsg.h
-rw-r--r-- 1 root root 3081 7月 9 16:45 field_types.h
-rw-r--r-- 1 root root 4468 7月 9 16:45 my_command.h
-rw-r--r-- 1 root root 3697 7月 9 16:45 my_compress.h
-rw-r--r-- 1 root root 2120 7月 9 16:45 my_list.h
drwxr-xr-x 2 root root 4096 7月 24 18:20 mysql
-rw-r--r-- 1 root root 37388 7月 9 16:45 mysql_com.h
-rw-r--r-- 1 root root 262882 7月 9 17:28 mysqld_error.h
-rw-r--r-- 1 root root 33601 7月 9 16:45 mysql.h
-rw-r--r-- 1 root root 3603 7月 9 16:45 mysql_time.h
-rw-r--r-- 1 root root 1143 7月 9 17:28 mysql_version.h
-rw-r--r-- 1 root root 7254 7月 9 17:28 mysqlx_ername.h
-rw-r--r-- 1 root root 4161 7月 9 17:28 mysqlx_error.h
-rw-r--r-- 1 root root 1856 7月 9 17:28 mysqlx_version.h
(base) ubuntu@Ubuntu22:~$ sudo ls /lib/x86_64-linux-gnu/ | grep mysql
libmysqlclient.a
libmysqlclient.so
libmysqlclient.so.21
libmysqlclient.so.21.2.43
libmysqlservices.a
如果你已经根据我的MySQL安装教程,安装了MySQL,那么大概率,系统上是已经安装好这个开发包工具的。因为根据MySQL官网的介绍,下载MySQL,自动会下载好C开发包,以及配置好库文件。
2. 官网下载安装(针对希望下载历史版本的情况)
- 下载地址:https://dev.mysql.com/downloads/。

- 点击进入历史版本存档页:

- 选择版本:

- 下载下来是一个
.tar.gz的压缩包,解压缩后,查看库目录结构:
(base) ubuntu@Ubuntu22:~/Downloads$ tree .
.
├── include
│ ├── big_endian.h
│ ├── byte_order_generic.h
│ ├── byte_order_generic_x86.h
│ ├── decimal.h
│ ├── errmsg.h
│ ├── keycache.h
│ ├── little_endian.h
│ ├── m_ctype.h
│ ├── m_string.h
│ ├── my_alloc.h
│ ├── my_byteorder.h
│ ├── my_compiler.h
│ ├── my_config.h
│ ├── my_dbug.h
│ ├── my_dir.h
│ ├── my_getopt.h
│ ├── my_global.h
│ ├── my_list.h
│ ├── my_pthread.h
│ ├── mysql
│ │ ├── client_authentication.h
│ │ ├── client_plugin.h
│ │ ├── client_plugin.h.pp
│ │ ├── get_password.h
│ │ ├── plugin_auth_common.h
│ │ ├── plugin_trace.h
│ │ ├── psi
│ │ │ ├── mysql_file.h
│ │ │ ├── mysql_idle.h
│ │ │ ├── mysql_mdl.h
│ │ │ ├── mysql_memory.h
│ │ │ ├── mysql_ps.h
│ │ │ ├── mysql_socket.h
│ │ │ ├── mysql_sp.h
│ │ │ ├── mysql_stage.h
│ │ │ ├── mysql_statement.h
│ │ │ ├── mysql_table.h
│ │ │ ├── mysql_thread.h
│ │ │ ├── mysql_transaction.h
│ │ │ ├── psi_base.h
│ │ │ ├── psi.h
│ │ │ └── psi_memory.h
│ │ ├── service_my_snprintf.h
│ │ └── service_mysql_alloc.h
│ ├── mysql_com.h
│ ├── mysql_com_server.h
│ ├── mysqld_ername.h
│ ├── mysqld_error.h
│ ├── mysql_embed.h
│ ├── mysql.h
│ ├── mysql_time.h
│ ├── mysql_version.h
│ ├── my_sys.h
│ ├── my_xml.h
│ ├── sql_common.h
│ ├── sql_state.h
│ ├── sslopt-case.h
│ ├── sslopt-longopts.h
│ ├── sslopt-vars.h
│ └── typelib.h
└── lib
├── libmysqlclient.a
├── libmysqlclient_r.a -> libmysqlclient.a
├── libmysqlclient_r.so -> libmysqlclient.so
├── libmysqlclient_r.so.18 -> libmysqlclient.so.18
├── libmysqlclient_r.so.18.3.0 -> libmysqlclient.so.18.3.0
├── libmysqlclient.so -> libmysqlclient.so.18
├── libmysqlclient.so.18 -> libmysqlclient.so.18.3.0
└── libmysqlclient.so.18.3.0
- 其中
include包含所有的方法声明,lib包含所有的方法实现(打包成库)。 - 接下来将库安装进系统,不会操作的请看我的Linux专栏中,关于动静态库的讲解:Linux从0到1——基础IO(下)【磁盘/文件系统/软硬链接/动静态库】
不推荐这样操作,太麻烦,不如
apt安装。
3. apt 安装
- 直接运行命令:
sudo apt install libmysqlclient-dev
apt会自动处理依赖和安装问题。
2. C++ 开发包下载和安装【Ubuntu】
1. 官网安装
- 下载地址:https://dev.mysql.com/downloads/。

- 点开后,找到历史版本的下载目录:

- 根据你的操作系统,和MySQL版本,选择对应版本的开发包:
- 最好选择8.0版本,这个版本兼容性最好。

- 下载带
dev字样的deb包,这是开发包:

- 之后直接在Ubuntu上执行命令,安装开发包:
sudo apt install ./libmysqlcppcomp-dev_8.0.33-1ubuntu22.04_amd64.deb
不推荐这样安装。
2. apt 安装
- 直接运行命令:
sudo apt install libmysqlcppconn-dev
3. 尝试链接mysql client,看看安装是否成功
接下来的讲解主要以C API为主,因为这个最简单。
- 通过
mysql_get_client_info()函数,来验证我们的引入是否成功:
#include <iostream>
#include <mysql/mysql.h>int main()
{std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;return 0;
}
- 编译并运行:
(base) ubuntu@Ubuntu22:~/Learn/test_db$ g++ -o test test.cc -lmysqlclient
(base) ubuntu@Ubuntu22:~/Learn/test_db$ ./test
mysql client version: 8.0.43
- 运行成功,即安装成功。
4. C API 接口介绍
官方学习文档:https://dev.mysql.com/doc/c-api/8.0/en/
4.1 基础操作
1. 初始化mysql_init()
- 要使用库,必须先进行初始化,参数传
nullptr即可,返回一个操作句柄。
MYSQL *mysql_init(MYSQL *mysql);
2. 链接数据库mysql_real_connect()
- 后两个参数暂时不考虑,用的时候分别传
nullptr和0即可。
MYSQL *mysql_real_connect(MYSQL *mysql,const char *host, // 服务端主机const char *user, // 用户名const char *passwd, // 密码const char *db, // 数据库unsigned int port, // 端口号const char *unix_socket, // 这两个参数暂时不考虑unsigned long client_flag)
- 初始化完毕之后,必须先链接数据库,在进行后续操作。(mysql网络部分是基于TCP/IP的)。
3. 设置客户端编码格式mysql_set_character_set()
- 必须保持客户端编码和服务端一致,否则会出现乱码问题。如果不设置,默认客户端的编码是
Latin1。
int mysql_set_character_set(MYSQL *mysql, const char *csname)
4. 下发mysql命令mysql_query()
- 第一个参数上面已经介绍过,第二个参数为要执行的
sql语句,如“select * from table”。
int mysql_query(MYSQL *mysql, const char *q);
sql执行完以后,如果是查询语句,我们当然还要读取数据,如果update,insert等语句,那么就看下操作成功与否即可。
4.2 查看查询结果
1. 接收返回结果mysql_store_result()
- 如果
mysql_query执行查询语句返回成功,那么我们就通过mysql_store_result这个函数来读取结果。原型如下:
MYSQL_RES *mysql_store_result(MYSQL *mysql);
- 该函数会调用MYSQL变量中的
st_mysql_methods中的read_rows函数指针来获取查询的结果。同时该函数会返回MYSQL_RES这样一个变量,该变量主要用于保存查询的结果。同时该函数malloc了一片内存空间来存储查询过来的数据,所以我们一定要记的free(result),不然是肯定会造成内存泄漏的。 - 执行完
mysql_store_result以后,其实数据都已经在MYSQL_RES变量中了,下面的api基本就是读取MYSQL_RES中的数据。
2. 获取结果行数mysql_num_rows()
my_ulonglong mysql_num_rows(MYSQL_RES *res);
3. 获取结果列数mysql_num_fields()
unsigned int mysql_num_fields(MYSQL_RES *res);
4. 获取列名mysql_fetch_fields()
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
- 伪代码,如:
int fields = mysql_num_fields(res);
MYSQL_FIELD *field = mysql_fetch_fields(res);
for(int i = 0; i < fields; i++){cout<<field[i].name<<" ";
}
5. 获取结果内容mysql_fetch_row()
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
- 它会返回一个
MYSQL_ROW变量,MYSQL_ROW其实就是char **,可以当成一个二维数组来用。

- 伪代码,如:
mysql_fetch_row()就像一个迭代器,每执行一次,它就会返回列表中的下一个char **。
MYSQL_ROW line;
for(int i = 0; i < nums; i++){line = mysql_fetch_row(res);for(int j = 0; j < fields; j++){cout<<line[j]<<" ";}cout<<endl;
}
6. 关闭mysql链接mysql_close()
void mysql_close(MYSQL *sock);
7. 另外,mysql C api还支持事务等常用操作,大家下来可以自行了解
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
my_bool STDCALL mysql_commit(MYSQL * mysql);
my_bool STDCALL mysql_rollback(MYSQL * mysql);
4.3 综合练习
1. 准备库和表
drop database if exists test_connect;
create database if not exists test_connect default character set utf8 collate utf8_general_ci;-- 使用数据库
use test_connect;-- 创建数据库表
drop table if exists people;
create table people (id int not null primary key auto_increment comment '编号',name varchar(20) not null default '' comment '姓名',age int not null default 0 comment '年龄',phone varchar(20) not null default '' comment '电话'
);
2. cpp代码
#include <iostream>
#include <string>
#include <vector>
#include <mysql/mysql.h>const std::string host = "127.0.0.1";
const std::string user = "root";
const std::string passwd = "root";
const std::string db = "test_connect";
const unsigned int port = 3306;int main()
{std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;MYSQL *my = mysql_init(nullptr);if (my == nullptr) {std::cerr << "init MySQL error" << std::endl;return 1;}if (mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr){std::cerr << "connect MySQL error" << std::endl;return 2;}std::cout << "connect success!" << std::endl;mysql_set_character_set(my, "utf8"); // 设置客户端编码为utf8std::vector<std::string> sqls;sqls.push_back("insert into people values(1, '张三', 20, '182371836487');");sqls.push_back("insert into people values(2, '李四', 18, '183424336487');");sqls.push_back("insert into people values(3, '王五', 40, '133371834324');");for (auto e : sqls) {if (0 == mysql_query(my, e.c_str())) {std::cout << e.c_str() << " success!" << std::endl;} else {std::cout << e.c_str() << " failed!" << std::endl;return 3;}}std::string sql = "select * from people;";if (0 != mysql_query(my, sql.c_str())) {std::cout << sql.c_str() << " failed!" << std::endl;return 4;}// MYSQL_RES 和查询结果有关MYSQL_RES *res = mysql_store_result(my);if (nullptr == res) {std::cerr << "mysql_store_result error" << std::endl;return 5;}int rows = mysql_num_rows(res); // 有多少行int fields = mysql_num_fields(res); // 有多少列std::cout << "行:" << rows << std::endl;std::cout << "列:" << fields << std::endl;// MYSQL_FIELD 和属性有关MYSQL_FIELD *fields_array = mysql_fetch_field(res);for (int i = 0; i < fields; i++) {std::cout << fields_array[i].name << "\t"; // name列名}std::cout << std::endl;// 提取内容for (int i = 0; i < rows; i++) {MYSQL_ROW row = mysql_fetch_row(res);for (int j = 0; j < fields; j++) {std::cout << row[j] << "\t"; // *(row+i)}std::cout << "\n";}// 获取当前数据库和表std::cout << "db: " << fields_array[0].db << " table: " << fields_array[0].table << std::endl; mysql_free_result(res); // 释放结果集mysql_close(my); // 释放句柄return 0;
}
3. 编写Makefile
mytest:test.ccg++ -o $@ $^ -std=c++11 -lmysqlclient.PHONY:
clean:rm -rf mytest
4. 编译并执行
(base) ubuntu@Ubuntu22:~/Learn/test_db$ make
g++ -o mytest test.cc -std=c++11 -lmysqlclient
(base) ubuntu@Ubuntu22:~/Learn/test_db$ ./mytest
mysql client version: 8.0.43
connect success!
insert into people values(1, '张三', 20, '182371836487'); success!
insert into people values(2, '李四', 18, '183424336487'); success!
insert into people values(3, '王五', 40, '133371834324'); success!
行:3
列:4
id name age phone
1 张三 20 182371836487
2 李四 18 183424336487
3 王五 40 133371834324
db: test_connect table: people
