Mysql系列--11、使用c/c++访问mysql服务
目录
一、准备
测试
二、创建对象
三、连接Mysql服务
四、下达指令
3.1增删改
增加
编码格式
删除
修改
3.2查询结果
结构体理解
打印属性
打印数据
前面我们已经学习并练习了本地命令行形式的sql语句的使用,可在以后开发中我们一般
不会直接命令行操作数据库,今天我们认识如何在自己的代码中调用指令对数据库进CURD操作。
所有操作函数均可以在mysql.com官方中查到使用手册
一、准备
使用c或其他语言操作数据库我们需要下载对应的第三方库,并把我们需要的头文件和库路径添加到对应程序编译链接时的查询位置。下载我们可以去官网下载。https://dev.mysql.com/downloads/
主要使用mysql.h文件:
库需要远程连接:
一般在/usr/lib64/libmysqlclient.so.20
或者在/lib64/libmysqlclient.so.20
我的在下面位置
测试
#include<iostream>
#include<mysql/mysql.h>int main()
{std::cout << "mysql test : " << mysql_get_client_info() << std::endl;return 0;
}
若能运行成功看到mysql版本就说明准备完成
二、创建对象
MYSQL * mysql_init(MYSQL*mysql)
eg:MYSQL*mfp = mysql_init(nullptr);返回:NULL if there was insufficient memory to allocate a new object.与mysql_close(MYSQL *)搭配使用,与打开关闭文件类似,防止空间浪费泄露
三、连接Mysql服务
申请完对象我们就可以连接mysql服务了。
首先我们要创建我们要连接的mysql服务用户,不要直接使用root用户,注意千万不要把mysql的端口暴露在公网中,这里只是测试,用完请立即删除,避免遭到攻击!!!
MYSQL *mysql_real_connect(MYSQL *mysql, --创建的mysql对象句柄const char *host, --连接的用户const char *user, --连接的主机const char *passwd, --连接所需的密码const char *db, --访问哪个库unsigned int port, --访问的端口const char *unix_socket, --域间套接字直接设为null unsigned long client_flag); --标记为设为0返回:A MYSQL* connection handler if the connection was successful, NULL if the connection was unsuccessful. For a successful connection, the return value is the same as the value of the first argument.
四、下达指令
连接成功后我们就可以利用相关语句执行我们的操作,由于select与其他操作不同所以分开描述
准备测试表:
int mysql_query(MYSQL *mysql,const char *stmt_str)mysql是我们申请的mysql对象,stmt_str是我们要操作的sql语句返回:Zero for success. Nonzero if an error occurred.
3.1增删改
增加
const char* sql = "insert into user values(1,'peter',18)";int n = mysql_query(mfp,sql);if(n == 0){std::cout << "query sucessed: " << sql << std::endl;}else{std::cerr << "query failed: " << mysql_error(mfp) << std::endl;return 1;}
编码格式
删除
删除编码格式错误的数据
修改
3.2查询结果
若我们直接查发现并没有任何数据回显,显然直接query拿不到查询结果
为了拿到和命令行一样的数据显示,mysql提供了一块空间用来储存获取的结果,并通过一些函数获得数据
MYSQL_RES *mysql_store_result(MYSQL *mysql)
将结果放在MYSQL_RES *的结构体中返回:A pointer to a MYSQL_RES result structure with the results. NULL if the statement did not return a result set or an error occurred.搭配void mysql_free_result(MYSQL_RES *result)进行空间的获取与释放
上面代码仅成功把结果放在了res结构体中,但我们还要打印才能拿到数据
结构体理解
对于上图结构体我们可以看到其中的字段均是指针类型,本质还是指向一个结构体
对于这种指向我们可以把它抽象成一个独特的二维数组进行理解,如图:
所以我们在打印数据时也可以利用行列数和[下标]进行数据访问
打印属性
获取二维数组列数my_ulonglong mysql_num_fields(MYSQL_RES*res)获取列属性内容MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES* res)
//打印列int field_count = mysql_num_fields(res);std::cout << "列数:" << field_count << std::endl;MYSQL_FIELD *field = mysql_fetch_fields(res);for(int i = 0; i < field_count; i++){std::cout << field[i].name << " ";}std::cout << std::endl;
打印数据
获取二维数组行数
my_ulonglong mysql_num_rows(MYSQL_RES*res)获取内容
MYSQL_ROW * mysql_fetch_row(MYSQL_RES*res)
返回:一个数据结构体
//打印列int field_count = mysql_num_fields(res);int row_count = mysql_num_rows(res);std::cout << "行数:" << row_count << std::endl;std::cout << "列数:" << field_count << std::endl;MYSQL_FIELD *field = mysql_fetch_fields(res);for(int i = 0; i < field_count; i++){std::cout << field[i].name << " ";}std::cout << std::endl;//打印数据(行)for(int i = 0; i < row_count; i++){MYSQL_ROW row = mysql_fetch_row(res);for(int j = 0; j < field_count; j++){std::cout << row[j] << " ";}std::cout << std::endl;}
代码;
#include<iostream>
#include<mysql/mysql.h>const char*host = "localhost";
const char*user = "con";
const char*password = "123456";
const char*database = "conn";
const unsigned int port = 3306;int main()
{// std::cout << "mysql test : " << mysql_get_client_info() << std::endl;MYSQL* mfp = mysql_init(nullptr);if (mfp == nullptr) {std::cerr << "申请mysql对象失败" << std::endl;return 1;}std::cout << "申请成功" << std::endl;MYSQL* conn = mysql_real_connect(mfp, host, user, password, database, port, nullptr, 0);if(conn == nullptr){std::cerr << "连接数据库失败" << std::endl;return 1;}std::cout << "连接成功" << std::endl;// //测试看是否连接成功// while(true)// {}//执行sql语句//统一编码格式mysql_set_character_set(mfp, "utf8");// const char* sql = "insert into user values(1,'peter',18)";// const char* sql = "insert into user values(2,'jimmy',19)";// const char* sql = "insert into user values(3,'张三',20)";// const char* sql = "delete from user where id=3";// const char* sql = "update user set age=21 where id=2";const char* sql = "select * from user";int n = mysql_query(mfp,sql);if(n == 0){std::cout << "query sucessed: " << sql << std::endl;}else{std::cerr << "query failed: " << mysql_error(mfp) << std::endl;return 1;}//获取结果集MYSQL_RES* res = mysql_store_result(mfp);if(res == nullptr){std::cerr << "获取结果集失败" << std::endl;return 1;}std::cout << "获取结果集成功" << std::endl;//打印列int field_count = mysql_num_fields(res);int row_count = mysql_num_rows(res);std::cout << "行数:" << row_count << std::endl;std::cout << "列数:" << field_count << std::endl;MYSQL_FIELD *field = mysql_fetch_fields(res);for(int i = 0; i < field_count; i++){std::cout << field[i].name << " ";}std::cout << std::endl;//打印数据(行)for(int i = 0; i < row_count; i++){MYSQL_ROW row = mysql_fetch_row(res);for(int j = 0; j < field_count; j++){std::cout << row[j] << " ";}std::cout << std::endl;}mysql_free_result(res);mysql_close(mfp);return 0;
}