1.mysql_init 初始化数据库
MYSQL *mysql_init(MYSQL *mysql);
作用:
初始化一个 MySQL 连接句柄。
为后续连接数据库做准备。
参数说明:
通常传
nullptr
(即NULL
),表示由函数内部自动分配并初始化一个MYSQL
结构体。你也可以传一个已存在的
MYSQL*
指针,但这较少用,主要用于多连接复用。返回值:
成功:返回一个初始化后的
MYSQL*
指针(你之后要用这个指针连接、操作数据库)。失败:返回
nullptr
(说明内存分配失败了)。MYSQL *conn = mysql_init(nullptr);
if (!conn) {
std::cerr << "Failed to init MySQL.\n";
return 1;
}相当于文件描述符*FILE
2.mysql_close 关闭数据库
void mysql_close(MYSQL *mysql);
作用:
关闭 MySQL 数据库连接。
释放资源(包括内部缓冲区、网络连接、内存等)。
参数说明:
- 传入的是你用
mysql_init()
得到的MYSQL*
指针。即使你没成功连接,也推荐调用
mysql_close()
来释放mysql_init()
分配的资源,保持代码整洁、稳定。
3.mysql_real_connect 连接数据库
MYSQL *mysql_real_connect( MYSQL *mysql, // mysql_init 返回的 MYSQL 指针 const char *host, // 主机地址,如 "localhost" 或 IP const char *user, // 用户名 const char *passwd, // 密码 const char *db, // 要连接的数据库名(可为 NULL) unsigned int port, // 端口号(MySQL 默认是 3306) const char *unix_socket,// 通常传 NULL,除非你用 socket 文件连接 unsigned long client_flag // 一般传 0,或如 CLIENT_MULTI_STATEMENTS );
成功:返回的是
MYSQL*
,也就是conn
本身。失败:返回
NULL
,你应该调用mysql_error()
打印错误信息。
4.mysql_set_character_set 设置字符串集
int mysql_set_character_set(MYSQL *mysql, const char *csname);
参数名 类型 说明 mysql
MYSQL*
已连接的 MySQL 对象指针( mysql_real_connect()
返回的)csname
const char*
要设置的字符集名称,如 "utf8"
、"utf8mb4"
、"gbk"
0
表示设置成功;非
0
表示失败,可使用mysql_error()
获取错误信息。如果要处理中文字符 需要设置字符串集mysql_set_character_set(my,"utf8")
常见字符集 用途 utf8
常见 UTF-8(最多3字节) utf8mb4
完整 UTF-8(最多4字节,支持 emoji)✅ 推荐 gbk
中文简体编码(兼容老系统) latin1
默认西欧编码(默认值,不建议)
5.mysql_query 向数据库发SQL语句
int mysql_query(MYSQL *mysql, const char *query);
参数名 类型 含义 mysql
MYSQL*
通过 mysql_init()
和mysql_real_connect()
获得的连接句柄query
const char*
要执行的 SQL 语句(字符串)
0
表示设置成功;非
0
表示失败,可使用mysql_error()
获取错误信息。insert update delete都能成功,select能成功 但select 查询的数据怎么获取打印出来?
获取打印select结果
1.mysql_store_result 返回结果集
MYSQL_RES *mysql_store_result(MYSQL *mysql);
mysql_store_result() 从服务器获取完整的查询结果 ,并将其缓存在本地内存 ,返回一个 MYSQL_RES* 结果集指针,供你遍历。
返回值 说明 MYSQL_RES*
(非空)查询成功,有结果集,可以继续用 mysql_fetch_row()
读取nullptr
查询失败或语句没有返回结果(如 INSERT),可用 mysql_error()
获取错误信息
MYSQL_RES:
MYSQL_RES 是 MySQL C API 中的一个结构体 类型,用来表示一次 SQL 查询(通常是 SELECT)返回的结果集。
typedef struct st_mysql_res { my_ulonglong row_count; // 行数 unsigned int field_count; // 列数 MYSQL_FIELD *fields; // 字段信息(列名等) unsigned long *lengths; // 每列值的长度 MYSQL_ROWS *data; // 所有数据的行链表 ... } MYSQL_RES;
2.mysql_num_rows 获取行数
my_ulonglong mysql_num_rows(MYSQL_RES *res);
获取结果集中总共的"行数"(记录数)
参数:
res
:由mysql_store_result()
返回的结果集指针返回值:
返回类型是
my_ulonglong
(64位无符号整数)表示总行数,例如:查询结果有 5 行,返回 5
3.mysql_num_fields 获取列数
unsigned int mysql_num_fields(MYSQL_RES *res);
获取结果集的"列数"(字段数)
4.mysql_fetch_row 获取一行数据
MYSQL_ROW mysql_fetch_row(MYSQL_RES *res);
从结果集中一行一行地提取数据,每调用一次,就"读取下一行",遍历到最好时返回 nullptr
就像迭代器一样从头到尾遍历一次
返回值:
返回一个
MYSQL_ROW
,实质上是char **
表示当前这一行的所有列的值(字符串形式)
MYSQL_ROW
是 MySQL C API 中用来表示查询结果中的一行数据 的结构,本质上是一个char**
类型(即:字符串数组)。
5.mysql_fetch_fields 获取属性信息数组
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
获取结果集的所有字段(列)的属性信息数组
返回一个
MYSQL_FIELD*
数组,每个元素表示一个字段
MYSQL_FIELD:
typedef struct st_mysql_field { char *name; // 字段名(如 "id") char *table; // 所属表名 char *db; // 所属数据库名 enum enum_field_types type; // 字段类型(如 MYSQL_TYPE_LONG、MYSQL_TYPE_STRING) unsigned int length; // 最大长度 unsigned int flags; // 属性(如是否为主键、是否可空) ... } MYSQL_FIELD;
成员名 类型 作用说明 name
char*
字段名称(如 "id"
,"name"
)table
char*
该字段所在的表名 db
char*
该字段所属的数据库名 type
枚举 字段的数据类型(如 MYSQL_TYPE_STRING
)length
unsigned int
字段最大长度 flags
unsigned int
标记属性(如 NOT_NULL_FLAG
,PRI_KEY_FLAG
)
6.mysql_free_result 释放结果集内存
void mysql_free_result(MYSQL_RES *res);
为什么必须调用?
mysql_store_result()
会把整个查询结果加载进内存;这个内存在客户端分配(不是自动释放);
所以你必须手动调用
mysql_free_result()
来清理它。否则,反复执行查询后内存会越来越多,造成内存泄漏甚至崩溃。
mysql简单使用
#include <iostream>
#include <string>
#include <mysql/mysql.h>
const std::string host = "localhost";
const std::string user = "wws";
const std::string password = "root1234";
const std::string db = "conn";
const unsigned int port = 3306;
int main()
{
// 1。初始化数据库 会分配并初始化一个 MYSQL 连接句柄
MYSQL *my = mysql_init(nullptr);
if (!my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
//2.连接数据库 也会返回权柄==my
if (mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error: " << mysql_error(my) << std::endl;
mysql_close(my);
return 2;
}
//3.设置字符串集 支持中文
mysql_set_character_set(my,"utf8");
//4.向数据库发SQL语句
std::string sql_in="insert into t_conn values(1,'王强','23912')";
std::string sql_up="update t_conn set name='asd' where name='王强'";
std::string sql_de="delete from t_conn where id=1";
std::string sql_se="select * from t_conn";
std::string&sql=sql_se;
int n=mysql_query(my,sql.c_str());
if(n==0) std::cout<<sql<<" success"<<std::endl;
else
{
std::cerr <<sql<< " mysql_query error: " << mysql_error(my) << std::endl;
mysql_close(my);
return 3;
}
//打印结果集
//1.获取结果集
MYSQL_RES* res=mysql_store_result(my);
//2.获取行数 列数
int rows=mysql_num_rows(res);
int fields=mysql_num_fields(res);
//3.获取属性信息 添加表头
MYSQL_FIELD* fields_array=mysql_fetch_field(res);
for(int i=0;i<fields;i++)
{
std::cout<<fields_array[i].name<<" ";
}
std::cout<<std::endl;
//4.获取行数据 遍历内容
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;
}
//5.释放结果集内存
mysql_free_result(res);
mysql_close(my);
}
