一、配置
首先,确保你已经安装了MySQL服务器和MySQL Connector/C库。在Linux上,你可以使用包管理器来安装这些,例如:
sudo apt-get install mysql-server libmysqlclient-dev
在ubuntu的机器上,库文件通常保存在 /lib/x86_64-linux-gnu/ 目录下
zyq@iZ0jlcvs1yxxmicafyy3kbZ:~/linux/Connect_Mysql$ ls /lib/x86_64-linux-gnu/ | grep mysql
libmysqlclient.a
libmysqlclient.so
libmysqlclient.so.21
libmysqlclient.so.21.2.40
libmysqlservices.a
库的头文件通常保存在 /usr/include/mysql/ 目录下
zyq@iZ0jlcvs1yxxmicafyy3kbZ:~/linux/Connect_Mysql$ ls /usr/include/mysql/
client_plugin.h my_compress.h mysql.h mysqlx_error.h
errmsg.h my_list.h mysql_time.h mysqlx_version.h
field_types.h mysql_com.h mysql_version.h plugin_auth_common.h
my_command.h mysqld_error.h mysqlx_ername.h udf_registration_types.h
在我们对访问mysql的程序编译时我们需要使用 -l 选项加上使用的库文件,注意动态库文件的名字是去掉前面的lib和后面的.so,例如:
connect:connect.cc
g++ -o $@ $^ -std=c++11 -lmysqlclient
而在Windows上,你需要从MySQL官方网站下载并安装MySQL服务器和MySQL Connector/C。
二、C语言API介绍
2.1 mysql_init
MYSQL *mysql_init(MYSQL *mysql);
这个函数的作用是进行初始化,要使用库,必须先进行初始化!如果函数执行成功他会返回一个MYSQL指针类型的操作数据库的句柄,失败则会返回null
他的参数接受一个MYSQL结构体的指针作为参数。如果传入NULL,则函数会自动分配一个新的MYSQL结构
2.2 mysql_real_connect()
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数据库服务器建立连接。
他的参数包括MYSQL结构体的指针、主机名、用户名、密码、数据库名、端口号、套接字路径和客户端标志等。
第一个参数 MYSQL是 C api中一个非常重要的变量(mysql_init的返回值),MYSQL类型是一个结构体,它主要用于存储与MySQL服务器连接的相关信息,如主机名、用户名、密码、当前连接的数据库、连接状态等。它也包含了一个叫 st_mysql_methods的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。
如果连接成功,返回MYSQL连接句柄(与第一个参数的值相同);如果连接失败,返回NULL。
注意:如果建立好链接之后,获取英文没有问题,获取中文是乱码的话我们需要手动设置一下编码格式, mysql_set_character_set(myfd, "utf8") 设置链接的默认字符集是utf8,原始默认是latin1
2.3 mysql_query
int mysql_query(MYSQL *mysql, const char *q);
他的作用是向MySQL数据库发送一条sql语句,参数包括MYSQL连接句柄和要执行的SQL查询字符串。如果查询成功,对于SELECT、SHOW、EXPLAIN或DESCRIBE语句,返回一个资源标识符;对于其他类型的SQL语句,返回TRUE。如果查询失败,返回FALSE。
2.4 mysql_close
void mysql_close(MYSQL *sock);
该函数的功能是关闭与MySQL数据库的连接,并释放与MYSQL结构体关联的资源,参数是MYSQL连接句柄。
有了上面的四个基础接口,我们就可以执行一部分sql命令了,接下来我们举个例子:在一个表中插入一个数据
#include<mysql/mysql.h>
#include<iostream>
#include<string>
#include<unistd.h>
int main()
{
MYSQL *mfp=mysql_init(nullptr);
if(mfp==nullptr)
{
std::cerr<<"MYSQL INIT FALSE!"<<std::endl;
return -1;
}
MYSQL *conn=mysql_real_connect(mfp,"8.130.115.39","connect","Zyq20040814.","test_connect",3306,nullptr,0);
if(conn==nullptr)
{
std::cerr<<"MYSQL CONNECT FALSE!"<<std::endl;
return -1;
}
mysql_set_character_set(mfp,"utf8");
std::string op="insert into people values(3)";
//std::string op="delete from people where id=3";
if(mysql_query(mfp,op.c_str())==0)
{
std::cout<<op.c_str()<<" success!"<<std::endl;
}
else
{
std::cerr<<op.c_str()<<" false!"<<std::endl;
}
mysql_close(mfp);
return 0;
}
问题:
对于增删改的操作来说我们只需要关心他是否执行成功就行,他们也是最简单的,但是我们想一下,mysql_query的返回值是一个整形,但是如果我们执行的SQL语句是SELECT类型的查找语句呢,那查询到的结果保存在哪里呢,如何让上层获取这些数据呢?我们继续学习
2.5 mysql_store_result
MYSQL_RES *mysql_store_result(MYSQL *mysql);
当执行查询时,MySQL服务器会处理查询并生成结果集,该函数可以从服务器检索查询的全部结果集,并将其存储在客户端。如果成功返回一个MYSQL_RES结果集对象,如果失败则返回NULL。
该函数会调用MYSQL变量中的st_mysql_methods中的 read_rows 函数指针来获取查询的结果。同时该 函数会返回MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。同时该函数malloc了一片内 存空间来存储查询过来的数据,所以我们一定要记的释放result,不然是肯定会造成内存泄漏的。 执行完mysql_store_result以后,其实数据都已经在MYSQL_RES 变量中了,下面的api基本就是读取 MYSQL_RES 中的数据。
2.6 mysql_num_rows
获取结果行数
my_ulonglong mysql_num_rows(MYSQL_RES *res);
2.7 mysql_num_fields
获取结果列数
unsigned int mysql_num_fields(MYSQL_RES *res);
2.7 mysql_fetch_fields
获取列名
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
MYSQL_FIELD是 MySQL C API 中用于描述查询结果集中列的信息的结构体。这个结构体包含了关于列的各种信息,如列名、数据类型、最大长度、是否允许为 NULL 等。
int fields = mysql_num_fields(res);
MYSQL_FIELD *field = mysql_fetch_fields(res);
int i = 0;
for(; i < fields; i++){
cout<<field[i].name<<" ";
}
cout<<endl;
2.8 mysql_fetch_row
获取结果内容
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
它会返回一个MYSQL_ROW变量,MYSQL_ROW其实就是char **.可以把他当成一个二维数组来用吧。
这个函数内部会自己维护一个类似于迭代器的指针,当我们访问完一行数据后他就会自动指向下一行的数据
i = 0;
MYSQL_ROW line;
for(; i < nums; i++){
line = mysql_fetch_row(res);
int j = 0;
for(; j < fields; j++){
cout<<line[j]<<" ";
}
cout<<endl;
}
案例:
将查询到的数据打印出来:
#include <mysql/mysql.h>
#include <iostream>
#include <string>
#include <unistd.h>
int main()
{
MYSQL *mfp = mysql_init(nullptr);
if (mfp == nullptr)
{
std::cerr << "MYSQL INIT FALSE!" << std::endl;
return -1;
}
MYSQL *conn = mysql_real_connect(mfp, "8.130.115.39", "connect", "Zyq20040814.", "test_connect", 3306, nullptr, 0);
if (conn == nullptr)
{
std::cerr << "MYSQL CONNECT FALSE!" << std::endl;
return -1;
}
mysql_set_character_set(mfp, "utf8");
std::string op = "select * from people";
if (mysql_query(mfp, op.c_str()) == 0)
{
std::cout << op.c_str() << " success!" << std::endl;
}
else
{
std::cerr << op.c_str() << " false!" << std::endl;
}
MYSQL_RES *res = mysql_store_result(mfp);
int row = mysql_num_rows(res);
int col = mysql_num_fields(res);
//获取列名
MYSQL_FIELD *field = mysql_fetch_fields(res);
for (int i = 0; i < col; i++)
{
std::cout<<field->name<<"\t";
}
std::cout<<std::endl;
//获取内容
for(int i=0;i<row;i++)
{
MYSQL_ROW line=mysql_fetch_row(res);;
for(int j=0;j<col;j++)
{
std::cout<<line[j]<<"\t";
}
std::cout<<std::endl;
}
mysql_free_result(res);
mysql_close(mfp);
return 0;
}