【MySQL】MySQL库

使用C/C++语言链接MySQL

  • [一、mysql connect](#一、mysql connect)
  • [二、mysql 接口介绍](#二、mysql 接口介绍)
    • [1. 初始化 mysql_init()](#1. 初始化 mysql_init())
    • [2. 链接数据库 mysql_real_connect()](#2. 链接数据库 mysql_real_connect())
    • [3. 执行 mysql 命令 mysql_query()](#3. 执行 mysql 命令 mysql_query())
    • [4. 获取执行结果 mysql_store_result()](#4. 获取执行结果 mysql_store_result())
    • [5. 释放空间](#5. 释放空间)
    • [5. 关闭 mysql 链接 mysql_close()](#5. 关闭 mysql 链接 mysql_close())

一、mysql connect

要使用C语言连接 mysql ,需要使用 mysql 官网提供的库,大家可以去官网下载。

由于我们以前在我们的 Linux 中已经安装了有关 MySQL 的安装包,它会默认帮我们安装了链接 MySQL 的头文件和库,我们可以查看一下:

其中 include 包含所有的方法声明, lib64 包含所有的方法实现(打包成库)。

如果大家在安装的时候没有这些头文件和库,可以执行如下指令安装:

				sudo yum install mysql-devel

安装好以后,我们可以通过 mysql_get_client_info() 接口函数,来验证我们是否引入成功:

				#include <iostream>
				#include <mysql/mysql.h>
				
				int main()
				{
				    std::cout <<  mysql_get_client_info() << std::endl;
				    return 0;
				}

结果如下:

如上,我们就成功引入了。

二、mysql 接口介绍

我们可以查看 MySQL5.7 的接口文档介绍。

1. 初始化 mysql_init()

想要使用库,必须先进行初始化,其函数为 mysql_init(),其在官方文档中的定义如下:

				MYSQL *mysql_init(MYSQL *mysql);

它的返回值是一个 MySQL* 的对象,我们可以这样初始化:

				MYSQL* fp = mysql_init(nullptr);

2. 链接数据库 mysql_real_connect()

初始化完毕之后,必须先链接数据库,在进行后续操作。(mysql 网络部分是基于 TCP/IP 的),其在官方文档的定义如下:

			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 clientflag);

其中 mysql 为我们初始化返回的对象;host 为需要链接的主机;user 为用户名;passwd 为用户密码;db 为使用的数据库名称;port 为端口号;后面两个参数不重要,我们可以设置为 nullptr0

而返回值如果成功是一个对象,否则就是空,接下来我们就可以使用这个接口了,例如以下代码,我们将函数中的参数在全局中用对应的名字定义了,所以直接传进去即可:

				int main()
				{
				    MYSQL* my = mysql_init(nullptr);
				    if(my == nullptr) return -1;
				
				    if(mysql_real_connect(my, host, user, passwd, db, port, nullptr, 0) == nullptr) return -1;
				
				    return 0;
				}

如果 nullptr 报错,修改一下 g++ 选项即可:

				g++ -o test test.cpp -std=c++11 -l mysqlclient -L /lib64/mysql

建立好链接之后,获取英文没有问题,如果获取中文是乱码,是由于原始默认是 latin1 ,我们可以通过接口设置链接的默认字符集是 utf8,如下:

				mysql_set_character_set(my, "utf8");

3. 执行 mysql 命令 mysql_query()

我们查看文档中的介绍:


				int mysql_query(MYSQL *mysql, const char *stmt_str);

其中返回值0为成功,非0则是失败;第一个参数上面已经介绍过,第二个参数为要执行的 sql 语句。我们先在库中创建一张表,如下:

接下来我们使用接口插入数据:

				int main()
				{
				    MYSQL* my = mysql_init(nullptr);
				    if(my == nullptr) return -1;
				
				    if(mysql_real_connect(my, host, user, passwd, db, port, nullptr, 0) == nullptr) return -1;
				
				    mysql_set_character_set(my, "utf8");
				
				    if(mysql_query(my, "insert into for_test values(1,'James')") != 0) return -1;
				    else std::cout << "query success" << std::endl;
				
				    return 0;
				}

运行结果如下:

接下来查看数据库中的表数据:

如果我们使用 mysql_query() 查看表数据呢?我们可以尝试一下:

				int main()
				{
				    MYSQL* my = mysql_init(nullptr);
				    if(my == nullptr) return -1;
				
				    if(mysql_real_connect(my, host, user, passwd, db, port, nullptr, 0) == nullptr) return -1;
				
				    mysql_set_character_set(my, "utf8");
				
				    if(mysql_query(my, "select * from for_test") != 0) return -1;
				    else std::cout << "query success" << std::endl;
				
				    return 0;
				}

我们看到,运行之后虽然成功了,但是什么都没有显示出来,这是因为 sql 如果是查询语句,我们还要读取数据!

4. 获取执行结果 mysql_store_result()

其实 my 中会存放每次读取到的结果,但是这个结果还需要我们再次提取出来,所以如果 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* 中的数据:

  • 获取结果行数 mysql_num_rows

      			my_ulonglong mysql_num_rows(MYSQL_RES *res);
    

其中 my_ulonglong 就是 unsigned long long,如下图:

  • 获取结果列数 mysql_num_fields

      			unsigned int mysql_num_fields(MYSQL_RES *res);
    
  • 获取列属性 mysql_fetch_fields

      			MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
    

mysql_fetch_fields 可以获取列的属性,其中获取列属性中的列名只需要指定 name 即可,如下:

			   // 属性
			    MYSQL_FIELD *field_array = mysql_fetch_fields(res);
			    for(int i = 0; i < fields; i++)
			    {
			        std::cout << field_array[i].name << "\t";
			    }
			    std::cout << std::endl;
  • 获取结果内容 mysql_fetch_row

      			MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
    

我们该怎么理解读取这个数据呢?首先需要知道,mysql 将所有的数据读取出来的时候全部都当作字符串。

其次我们在 select * from for_test 的时候,显示出来的是一个表格的形状,所以我们就可以给它进行按行按列分割,如下图:

其实我们可以把这个返回的 MYSQL_ROW 变量看作是一个 char** 的指针,如下图:

更重要的是,返回的这个 MYSQL_ROW 的变量可以像迭代器一样使用,我们不需要手动进行迭代,它会帮我们自己迭代,例如:

			    // 内容
			    for(int i = 0; i < rows; i++)
			    {
			        MYSQL_ROW line = mysql_fetch_row(res);
			        for(int j = 0; j < fields; j++)
			        {
			            std::cout << line[j] << "\t";
			        }
			        std::cout << std::endl;
			    }

5. 释放空间

我们上面开辟的空间我们最后也要释放掉,就是 char** 这段空间,接口为:

我们在最后直接调用即可,参数就是我们上面的 res.

5. 关闭 mysql 链接 mysql_close()

				void mysql_close(MYSQL *mysql);

关闭链接我们直接调用以上方法即可,参数就是我们初始化的返回值。

相关推荐
Ai 编码助手10 分钟前
MySQL中distinct与group by之间的性能进行比较
数据库·mysql
霁月风19 分钟前
设计模式——适配器模式
c++·适配器模式
陈燚_重生之又为程序员25 分钟前
基于梧桐数据库的实时数据分析解决方案
数据库·数据挖掘·数据分析
caridle27 分钟前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
白云如幻28 分钟前
MySQL排序查询
数据库·mysql
萧鼎30 分钟前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸31 分钟前
【一些关于Python的信息和帮助】
开发语言·python
疯一样的码农31 分钟前
Python 继承、多态、封装、抽象
开发语言·python
^velpro^32 分钟前
数据库连接池的创建
java·开发语言·数据库
苹果醋336 分钟前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx