使用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, //一般设为nullptrunsigned 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**的typedefMYSQL_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 李四