使用C语言访问MySQL
- 一.检查第三方库是否配置成功
- 二.MySQL 常用接口
- 1.创建,销毁操作句柄
- 2.使用句柄连接数据库
- 3.向 mysqld 发送指令
- 4.查询相关函数
- 三.使用示例
一.检查第三方库是否配置成功
想要使用代码连接数据库,必须使用 MySQL 官方提供的第三方库。早在我们第一节使用 yum 安装 MySQL 的时候,
就安装了三个东西:MySQL 客户端,MySQL 服务端,MySQL 开发包(库)。所以我们只需检查一下环境是否就绪。
//1.检查是否有MySQL库
[liuyi@centos-7 usr]$ ls /usr/lib64/mysql/
libmysqlclient.a libmysqlclient_r.so.18.1.0 libmysqlclient.so.18 libmysqlclient.so.20 libmysqlservices.a plugin
libmysqlclient_r.so.18 libmysqlclient.so libmysqlclient.so.18.1.0 libmysqlclient.so.20.3.31 mecab
//2.检查是否有MySQL头文件
[liuyi@centos-7 usr]$ ls /usr/include/mysql/
big_endian.h keycache.h my_command.h my_getopt.h mysqld_ername.h mysqlx_ername.h my_xml.h plugin_validate_password.h thr_cond.h
binary_log_types.h little_endian.h my_compiler.h my_global.h mysqld_error.h mysqlx_error.h plugin_audit.h sql_common.h thr_mutex.h
byte_order_generic.h m_ctype.h my_config.h my_list.h mysql_embed.h mysqlx_version.h plugin_ftparser.h sql_state.h thr_rwlock.h
byte_order_generic_x86.h m_string.h my_config_x86_64.h mysql mysql.h my_sys.h plugin_group_replication.h sslopt-case.h typelib.h
decimal.h my_alloc.h my_dbug.h mysql_com.h mysql_time.h my_thread.h plugin.h sslopt-longopts.h
errmsg.h my_byteorder.h my_dir.h mysql_com_server.h mysql_version.h my_thread_local.h plugin_keyring.h sslopt-vars.h
如果以上东西没有,则执行以下命令安装开发包:
sudo yum install -y mysql-devel
#include <mysql/mysql.h>
#include <iostream>
using namespace std;
int main()
{
cout << "mysql client version: " << mysql_get_client_info() << endl;
return 0;
}
//编译命令如下:
//g++ -o test test.cc -std=c++11 -L /usr/lib64/mysql -l mysqlclient
//如果编译成功,则说明环境没有问题
[liuyi@centos-7 test_db]$ ./test
mysql client version: 5.7.44
二.MySQL 常用接口
MySQL 官方文档
1.创建,销毁操作句柄
MYSQL* mysql_init(MYSQL* mysql);
功能:创建一个mysql对象,这就是我们操作的句柄
返回值:如果返回NULL则创建失败,否则返回一个创建出的对象
void mysql_close(MYSQL* mysql);
功能:销毁mysql对象
2.使用句柄连接数据库
MYSQL* mysql_real_connect(MYSQL *mysql, //句柄
const char *host, //mysqld所在主机
const char *user, //mysql用户名
const char *passwd, //登录密码
const char *db, //数据库名
unsigned int port, //mysqld所在端口
const char *unix_socket, //一般设为nullptr
unsigned long client_flag) //一般设为0
功能:连接数据库
返回值:连接失败返回nullptr,连接成功返回句柄本身
3.向 mysqld 发送指令
int mysql_query(MYSQL *mysql,
const char *stmt_str)
功能:向mysqld发送指令执行
返回值:0表示语句执行成功,非0表示执行失败
int mysql_set_character_set(MYSQL *mysql,
const char *csname)
功能:设置当前连接的字符串编码格式,必须让它和mysqld的编码格式保持一致,否则中文会乱码
返回值:为0则设置成功
4.查询相关函数
select查询到的数据会保存在MYSQL对象中
MYSQL_RES* mysql_store_result(MYSQL *mysql);
功能:将保存在MySQL对象中的数据进行整合,把查询结果保存到MYSQL_RES对象中
返回值:为nullptr表示失败
说明:
MYSQL_RES也是第三方库定义的一个结构体类型,其内部维护了一个char**的数组,
以后处理select结果会频繁用到该对象;
mysql_store_result内部肯定会malloc一段空间用于保存结果,最后一定要调用相应函数释放以免内存泄露
unsigned int mysql_num_rows(MYSQL_RES *res);
功能:返回表的行数(不包含字段行)
unsigned int mysql_num_fields(MYSQL_RES *res);
功能:返回表的列数(不包含字段行)
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
功能:获取一行的结果,每次调用后会自动迭代
返回值:为nullptr表示获取失败
说明:MYSQL_ROW是对char**的typedef
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
功能:返回该表的所有字段的详细信息
返回值:为nullptr表示获取失败
说明:MYSQL_FIELD是一个结构体类型,包含一个字段的详细信息,如字段名,属性,所属表的名称等
void mysql_free_result(MYSQL_RES* res)
功能:释放mysql_store_result中申请的空间,释放后就不要试图访问res了
三.使用示例
#include <mysql/mysql.h>
#include <iostream>
#include <cassert>
const char *host = "127.0.0.1"; //写localhost也行
const char *user = "ly";
const char *password = "**********"; //密码不方便透露
const char *db = "test_db";
unsigned int port = 3306;
using namespace std;
int main()
{
//1.创建句柄
MYSQL *mysql = mysql_init(nullptr);
if (mysql == nullptr)
{
cout << "创建MySQL对象失败" << endl;
return 1;
}
//2.连接数据库并修改本次连接中客户端的编码方式
assert(mysql_real_connect(mysql, host, user, password, db, port, nullptr, 0) != nullptr);
mysql_set_character_set(mysql, "utf8");
//3.执行建表,插入,查询语句
assert(mysql_query(mysql, "create table test_tb(id int, name varchar(20))") == 0);
assert(mysql_query(mysql, "insert into test_tb values(1, '张三')") == 0);
assert(mysql_query(mysql, "insert into test_tb values(2, '李四')") == 0);
assert(mysql_query(mysql, "select * from test_tb") == 0);
//4.将查询结果保存到res中
MYSQL_RES *res = mysql_store_result(mysql);
//5.处理查询结果
int rows = mysql_num_rows(res);
int cols = mysql_num_fields(res);
MYSQL_FIELD *fields_array = mysql_fetch_fields(res);
for (int i = 0; i < cols; i++)
{
cout << fields_array[i].name << "\t";
}
cout << endl;
for (int i = 0; i < rows; i++)
{
char **line = mysql_fetch_row(res);
for (int j = 0; j < cols; j++)
{
cout << line[j] << "\t";
}
cout << endl;
}
//6.释放查询结果
mysql_free_result(res);
//7.销毁句柄
mysql_close(mysql);
return 0;
}
//编译运行结果:
[liuyi@centos-7 test_db]$ ./test
id name
1 张三
2 李四