文章目录
- 前言
- 一、使用步骤
- 1.MYSQL *mysql_init(MYSQL *mysql);
- 2.MYSQL *mysql_real_connect
- int mysql_query(MYSQL *mysql, const char *q);
- MYSQL_RES *mysql_store_result(MYSQL *mysql);
- my_ulonglong mysql_num_rows(MYSQL_RES *res);
- unsigned int mysql_num_fields(MYSQL_RES *res);
- MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
- MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
- 所有源代码
前言
通过之前的章节,我们已经学会了MySQL的大部分基本操作和概念,今天我们将要学习通过C语言接口来访问MySQL。
需要注意的是,今天我们要使用的接口都来自于第三方库,这个库是由MySQL提供的,我们需要用到 mysql.h 和 mysqlclient.so ,头文件一般在/usr/include/mysql/
,动态库文件有的在/usr/lib/
或者/usr/lib64/
中,不过我的就在/usr/lib/x86_64-linux-gnu/
目录下,所以如果你找不到的话,可以直接使用sudo find / -name libmysqlclient.so
来直接查找。
当然前提是你的主机安装了mysql,一般会自动给你添加这些库文件。
g++ -o test test.cc -std=c++11 -lmysqlclient -L /usr/lib/x86_64-linux-gnu/
一、使用步骤
1.MYSQL *mysql_init(MYSQL *mysql);
就像是我们之前的要使用Windos下的网络通信一样,需要先初始化环境,这个接口函数就是初始化当前的环境。
MYSQL *mysql_ptr = mysql_init(nullptr);
后续我们要进行对mysql进行连接就需要用上该返回值MYSQL*
2.MYSQL *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_init的返回值,
参数const char *user,
const char *passwd,
const char *db,
unsigned int port 很显而易见。
至于最后两个参数我们这里暂时不作考虑。
如果连接失败,则会返回nullptr。
#include <iostream>
#include <mysql/mysql.h>
#include <string>
const std::string host = "127.0.0.1";
const std::string user = "fengjunzi";
const std::string passwd = "wdnmdsb1";
const std::string database = "test_db";
const unsigned int port = 3306;
int main()
{
MYSQL *mysql_ptr = mysql_init(nullptr);
if (mysql_ptr == nullptr)
{
std::cerr << "MySQL Init Error" << std::endl;
mysql_close(mysql_ptr);
exit(1);
}
if (mysql_real_connect(mysql_ptr, host.c_str(), user.c_str(), passwd.c_str(), database.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "MySQL Connect Error" << std::endl;
mysql_close(mysql_ptr);
exit(2);
}
std::cout << "MySQL Connect Success" << std::endl;
}
int mysql_query(MYSQL *mysql, const char *q);
这个函数就是用来对连接的mysql下达指令的函数,参数const char *q就是你下达的指令的字符串。
//模拟mysql输入命令行
while (true)
{
std::cout << "mysql> ";
if (!std::getline(std::cin, mysql_statement) || mysql_statement == "quit" || mysql_statement == "quit;")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(mysql_ptr, mysql_statement.c_str());
if (n == 0)
{
std::cout << "MySQL Query Success" << std::endl;
}
else
{
std::cerr << "MySQL Query Error" << std::endl;
break;
}
通过mysql_query我们确实可以给mysql下达指令,但是,我们如果调用select,其实是没有反应的,那么如果我们要读取内容显示出来,应该怎么办呢?
如何做到获取select结果?
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 中的数据。
my_ulonglong mysql_num_rows(MYSQL_RES *res);
获取结果行数mysql_num_rows
unsigned int mysql_num_fields(MYSQL_RES *res);
获取结果列数mysql_num_fields
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
获取列名mysql_fetch_fields
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
用于获取行内容数据,返回的MYSQL_ROW其实是一个char**。
if (mysql_statement.substr(0,6) == "select")
{
MYSQL_RES *result = mysql_store_result(mysql_ptr);
MYSQL_FIELD *field_array = mysql_fetch_fields(result); // 获取列名
unsigned int fields = mysql_num_fields(result); // 获取列数
unsigned int rows = mysql_num_rows(result); // 获取行数
for (int i = 0; i < fields; i++)
{
std::cout << field_array[i].name << "\t";
}
std::cout << std::endl;
for (int i = 0; i < rows; i++)
{
MYSQL_ROW line = mysql_fetch_row(result); // typedef MYSQL_ROW char**
for (int j = 0; j < fields; j++)
{
std::cout << line[j] << "\t";
}
std::cout << std::endl;
}
free(result); //记得free,不然会造成内存泄漏!
}
所有源代码
#include <iostream>
#include <mysql/mysql.h>
#include <string>
const std::string host = "127.0.0.1";
const std::string user = "fengjunzi";
const std::string passwd = "wdnmdsb1";
const std::string database = "test_db";
const unsigned int port = 3306;
int main()
{
// std::cout << "mysql version: " << mysql_get_client_info() << std::endl;
MYSQL *mysql_ptr = mysql_init(nullptr);
if (mysql_ptr == nullptr)
{
std::cerr << "MySQL Init Error" << std::endl;
mysql_close(mysql_ptr);
exit(1);
}
if (mysql_real_connect(mysql_ptr, host.c_str(), user.c_str(), passwd.c_str(), database.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "MySQL Connect Error" << std::endl;
mysql_close(mysql_ptr);
exit(2);
}
std::cout << "MySQL Connect Success" << std::endl;
mysql_set_character_set(mysql_ptr, "utf8"); //将我向目标mysql发送的字符编码变为utf8
// std::string mysql_statement = "insert into user (name, age) values('李四',13)";
// std::string mysql_statement = "select * from user";
std::string mysql_statement;
while (true)
{
std::cout << "mysql> ";
// mysql_statement = "";
if (!std::getline(std::cin, mysql_statement) || mysql_statement == "quit" || mysql_statement == "quit;")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(mysql_ptr, mysql_statement.c_str());
if (n == 0)
{
std::cout << "MySQL Query Success" << std::endl;
}
else
{
std::cerr << "MySQL Query Error" << std::endl;
break;
}
if (mysql_statement.substr(0,6) == "select")
{
MYSQL_RES *result = mysql_store_result(mysql_ptr);
MYSQL_FIELD *field_array = mysql_fetch_fields(result); // 获取列名
unsigned int fields = mysql_num_fields(result); // 获取列数
unsigned int rows = mysql_num_rows(result); // 获取行数
for (int i = 0; i < fields; i++)
{
std::cout << field_array[i].name << "\t";
}
std::cout << std::endl;
for (int i = 0; i < rows; i++)
{
MYSQL_ROW line = mysql_fetch_row(result); // typedef MYSQL_ROW char**
for (int j = 0; j < fields; j++)
{
std::cout << line[j] << "\t";
}
std::cout << std::endl;
}
free(result); //记得free,不然会造成内存泄漏!
}
}
mysql_close(mysql_ptr);
return 0;
}