要使用C语言连接mysql,需要使用mysql官网提供的库,大家可以去MySQL官网下载。
1.引入库
1.选择Download Archivs
因为我们要连接的是C语言,所以选择Connector/C。
选择合适的版本下载,我这里
下载完之后,我们使用rz命令将刚刚下载的包传送到服务器上
传送完成之后我们会发现多了一个文件。
使用tar命令将压缩包解压会生成一个目录。
目录中包含了include目录和lib目录,include中存放的是mysql相关的头文件,而lib中就是动静态库。
2.使用库
我们先使用库中的函数。
#include <stdio.h>
#include <mysql.h>
int main()
{
printf("mysql client Version: %s\n", mysql_get_client_info());
return 0;
}
当我们在项目中想使用这个库,我们可以先创建两个软连接,连接到include和lib目录下。
此时我们编译后会生成一个可执行文件
- -I:用于指明头文件搜索路径
- -L:用于指明库文件搜索路径
- -l:指明库文件中的哪一个库
但是这个可执行文件是不能运行的,使用mysqlclient库时,在系统的搜索路径下没找到。此时我们有三种方案
1.将mysqlclient库文件拷贝到系统默认的库文件搜索路径中。
2.将mysqlclient库文件所在路径拷贝到LD_LIBRARY_PATH环境变量中。
3.将mysqlclient库文件所在的路径保存到 /etc/ld.so.conf.d/ 目录下以 .conf为后缀的文件当中,并使用ifconfig命令更新
解决成功之后,我们就可以正常运行了
刚刚运行的结果就是我们下载的mysql库的版本。
3.mysql接口介绍
3.1mysql对象
连接数据库前,我们需要创建一个MySQL对象
MYSQL *mysql_init(MYSQL *mysql);
参数为null时,函数自动返回一个MySQL对象,如果参数为一个地址,函数会在该地址处帮你完成初始化。
MYSQL是 C api中一个非常重要的变量(mysql_init的返回值),里面内存非常丰富,有port,dbname,charset等连接基本参数。它也包含了一个叫 st_mysql_methods的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。
3.2mysql连接
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_init创建的对象
- host:要连接的MySQL服务器IP地址
- user:连接MySQL服务器时的用户名
- passwd:连接MySQl服务器时的用户密码
- db:你要访问的数据库
- port:要连接的MySQL服务器的端口号
- unix_socket:连接时应该使用的套接字或者管道,通常为NULL
- clientflag:表示允许特定功能,通常为0
连接成功返回MySQL对象(与第一个参数值相同),失败返回NULL。
3.3mysql关闭
void mysql_close(MYSQL* sock);
与mysql_init搭配使用,释放mysql_init创建的对象。
#include <iostream>
#include <string>
#include <unistd.h>
#include <mysql/mysql.h>
const std::string host = "127.0.0.1";
const std::string user = "cola";
const std::string possward = "hsu@177118";
const std::string db = "student";
const unsigned int port = 3306;
int main()
{
MYSQL *my = mysql_init(nullptr);
if (nullptr == my)
{
std::cerr << "init mysql error" << std::endl;
return 1;
}
MYSQL *ret = mysql_real_connect(my, host.c_str(), user.c_str(), possward.c_str(), db.c_str(), port,
nullptr, 0);
if (ret == nullptr)
{
std::cerr << "mysql_real_connect error" << std::endl;
return 2;
}
std::cout << "数据库连接成功" << std::endl;
mysql_close(my);
std::cout << "数据库关闭成功" << std::endl;
return 0;
}
这样就连接成功了。
3.4 mysql命令
int mysql_query(MYSQL *mysql, const char *q);
第一个参数上面已经介绍过,第二个参数为要执行的sql语句,如“select * from table”,最后可以不带分号。
3.5设置编码格式
mysql_set_character_set(myfd, "utf8");
建立好链接之后,获取英文没有问题,如果获取中文是乱码(两端编码格式不同)设置链接的默认字符集是utf8,原始默认是latin1。
- 测试:
#include <iostream>
#include <string>
#include <unistd.h>
#include <mysql/mysql.h>
const std::string host = "127.0.0.1";
const std::string user = "cola";
const std::string possward = "hsu@177118";
const std::string db = "student";
const unsigned int port = 3306;
int main()
{
//连接数据库
MYSQL *my = mysql_init(nullptr);
if (nullptr == my)
{
std::cerr << "init mysql error" << std::endl;
return 1;
}
//设置编码格式
mysql_set_character_set(my, "utf8");
MYSQL *ret = mysql_real_connect(my, host.c_str(), user.c_str(), possward.c_str(), db.c_str(), port,
nullptr, 0);
if (ret == nullptr)
{
std::cerr << "mysql_real_connect error" << std::endl;
return 2;
}
std::cout << "数据库连接成功" << std::endl;
//插入数据
std::string sql = "insert into user values (8, 56, '周伯通')";
int n = mysql_query(my, sql.c_str());
if (n != 0)
{
std::cerr << "mysql_query error" << std::endl;
}
else
{
std::cout << "下达指令成功" << std::endl;
}
//关闭数据库
mysql_close(my);
std::cout << "数据库关闭成功" << std::endl;
return 0;
}
这段代码就是连接数据库后,向数据库中插入信息。
当我们执行这段代码之后会发生,真的成功插入了。
3.6获取查询结果
如果我们直接使用mysql_query函数,并在参数中使用select是无法观察到查询结果的。如果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);
获取结果列数mysql_num_fields
unsigned int mysql_num_fields(MYSQL_RES *res);
获取列名mysql_fetch_fields,返回的是一个结构体,结构体中保存着对应列的列属性。
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
通过这几个函数的搭配就能成功获取到查询结果。
例如:
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;
上面的代码就是获得查询结果的列信息。
获取结果内容mysql_fetch_row
它会返回一个MYSQL_ROW变量,MYSQL_ROW其实就是char **.就当成一个二维数组来用吧。
- 演示:
#include <iostream>
#include <string>
#include <unistd.h>
#include <mysql/mysql.h>
const std::string host = "127.0.0.1";
const std::string user = "cola";
const std::string possward = "hsu@177118";
const std::string db = "student";
const unsigned int port = 3306;
int main()
{
// 连接数据库
MYSQL *my = mysql_init(nullptr);
if (nullptr == my)
{
std::cerr << "init mysql error" << std::endl;
return 1;
}
// 设置编码格式
mysql_set_character_set(my, "utf8");
MYSQL *ret = mysql_real_connect(my, host.c_str(), user.c_str(), possward.c_str(), db.c_str(), port,
nullptr, 0);
if (ret == nullptr)
{
std::cerr << "mysql_real_connect error" << std::endl;
return 2;
}
std::cout << "数据库连接成功" << std::endl;
// 查询数据
// std::string sql = "insert into user values (8, 56, '周伯通')";
std::string sql = "select * from user";
int n = mysql_query(my, sql.c_str());
if (n != 0)
{
std::cerr << "mysql_query error" << std::endl;
}
else
{
std::cout << "下达指令成功" << std::endl;
}
// 获取查询结果
MYSQL_RES *res = mysql_store_result(my);
if (nullptr == res)
{
std::cerr << "mysql_store_result error" << std::endl;
return 3;
}
//打印列名
int fieldnum = mysql_num_fields(res);
MYSQL_FIELD *field = mysql_fetch_fields(res);
for (int i = 0; i < fieldnum; i++)
{
std::cout << field[i].name << " ";
}
std::cout << std::endl;
//打印内容
int rows = mysql_num_rows(res);
int fields = mysql_num_fields(res);
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] << " ";
}
std::cout << std::endl;
}
free(res);
// 关闭数据库
mysql_close(my);
std::cout << "数据库关闭成功" << std::endl;
return 0;
}
最终也是将数据库中的内容成功打印了