1. mysql_init
MYSQL *mysql_init(MYSQL *mysql);
mysql_init函数的作用:创建一个 MYSQL 对象(该对象用于连接数据库)。
mysql_init函数的参数:
① mysql:MYSQL 结构体指针,一般设置为 NULL 。
mysql_init函数的返回值:
① 成功,返回一个指向 MYSQL 对象的指针。
② 失败,返回 NULL 。
MYSQL 对象的定义如下:
typedef struct st_mysql
{
NET net; /* Communication parameters */
unsigned char *connector_fd; /* ConnectorFd for SSL */
char *host,*user,*passwd,*unix_socket,*server_version,*host_info;
char *info, *db;
struct charset_info_st *charset;
MYSQL_FIELD *fields;
MEM_ROOT field_alloc;
my_ulonglong affected_rows;
my_ulonglong insert_id; /* id if insert on table with NEXTNR */
my_ulonglong extra_info; /* Not used */
unsigned long thread_id; /* Id for connection in server */
unsigned long packet_length;
unsigned int port;
unsigned long client_flag,server_capabilities;
unsigned int protocol_version;
unsigned int field_count;
unsigned int server_status;
unsigned int server_language;
unsigned int warning_count;
struct st_mysql_options options;
enum mysql_status status;
my_bool free_me; /* If free in mysql_close */
my_bool reconnect; /* set to 1 if automatic reconnect */
/* session-wide random string */
char scramble[SCRAMBLE_LENGTH+1];
my_bool unused1;
void *unused2, *unused3, *unused4, *unused5;
LIST *stmts; /* list of all statements */
const struct st_mysql_methods *methods;
void *thd;
/*
Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag
from mysql_stmt_close if close had to cancel result set of this object.
*/
my_bool *unbuffered_fetch_owner;
/* needed for embedded server - no net buffer to store the 'info' */
char *info_buffer;
void *extension;
} MYSQL;
MYSQL 对象里有很多连接基本参数,它也包含了一个叫 st_mysql_methods 的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。
2. 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_real_connect函数的作用:连接数据库。
mysql_real_connect函数的参数:
① mysql:MYSQL 对象指针。
② host:要连接的 MySQL 服务器的 IP 地址。
③ user:用户名,以哪个用户身份连接。
④ passwd:用户密码。
⑤ db:要连接的数据库。
⑥ port:要连接的 MySQL 服务器的端口号。
⑦ unix_socket:通常设置为 NULL 。
⑧ clientflag:通常设置为 0 。
mysql_real_connect函数的返回值:
① 成功,返回一个指向 MYSQL 对象的指针,与第一个参数 mysql 的值相同。
② 失败,返回 NULL 。
3. mysql_close
void mysql_close(MYSQL *sock);
mysql_close函数的作用:关闭数据库连接。
mysql_close函数的参数:
① sock:MYSQL 对象指针。
mysql_close函数的返回值:无。
4. mysql_set_character_set
在连接数据库之后,需要先统一客户端和服务器的编码格式,避免在数据交互的过程中出现乱码。
int mysql_set_character_set(MYSQL *mysql, const char *csname);
mysql_set_character_set函数的作用:设置编码格式。
mysql_set_character_set函数的参数:
① mysql:MYSQL 对象指针。
② csname:要设置成哪种字符集。
mysql_set_character_set函数的返回值:
① 成功,为 0 。
② 失败,为非 0 。
5. mysql_query
int mysql_query(MYSQL *mysql, const char *q);
mysql_query函数的作用:下发 SQL 请求。
mysql_query函数的参数:
① mysql:MYSQL 对象指针。
② q:要执行的 SQL 语句(语句结尾可以不带分号)。
mysql_query函数的返回值:
① 成功,为 0 。
② 失败,为非 0 。
6. mysql_store_result
MYSQL_RES *mysql_store_result(MYSQL *mysql);
mysql_store_result函数的作用:获取查询结果。
mysql_store_result函数的参数:
① mysql:MYSQL 对象指针。
mysql_store_result函数的返回值:
① 成功,返回一个指向 MYSQL_RES 对象的指针。
② 失败,返回 NULL 。
该函数会调用 MYSQL 变量中的 st_mysql_methods 中对应的函数指针来获取查询结果。
该函数会 malloc 出一个 MYSQL_RES 结构体变量,将获取到的查询结果保存到该变量中,最后返回该变量的指针。
由于 MYSQL_RES 的内存空间是 malloc 出来的,所以在使用完之后一定要记得调用 free 函数(mysql_free_result函数)来释放对应的内存空间,否则会造成内存泄漏。
执行完mysql_store_result以后,其实要查询的数据都已经在 MYSQL_RES 变量中了,下面的函数基本就是读取 MYSQL_RES 中的数据,参数都是 MYSQL_RES 对象指针:
// 获取结果的行数
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_fetch_row函数的返回值 MYSQL_ROW:
MYSQL_ROW,即结果中的一行记录,对应着多个列信息,实际上就是一个字符串数组,因此,MYSQL_ROW 类型,本质就是 char** 类型,其定义如下:
typedef char **MYSQL_ROW; /* return data as array of strings */
7.mysql_free_result()
void mysql_free_result(MYSQL_RES *result);
作用:用于释放前面 mysql_store_result 分配的内存。
三、使用示例
1.连接数据库和关闭数据库连接
#include <stdio.h>
#include <winsock.h>
#include <mysql.h>
const char host[] = "127.0.0.1"; // MySQL所在机器的ip
const int port = 0; // MySQL所在机器的端口
const char db[] = "test"; // 数据库名
const char user[] = "root"; // 用户名
const char passwd[] = "test123"; // 用户密码
int main()
{
//1、获取MySQL实例(相当于创建了一个MySQL句柄)
MYSQL* ms = mysql_init(nullptr);
//2、连接数据库
if(mysql_real_connect(ms, host, user, passwd, db, port, nullptr, 0) == nullptr) {
printf("数据库连接失败!\n");
return 1;
}
printf("数据库连接成功!\n");
//3、访问数据库
//4、关闭数据库连接
mysql_close(ms);
printf("数据库连接关闭成功!\n");
return 0;
}
2.访问数据库
mysql_query:
#include <stdio.h>
#include <winsock.h>
#include <mysql.h>
const char host[] = "127.0.0.1"; // MySQL所在机器的ip
const int port = 0; // MySQL所在机器的端口
const char db[] = "test"; // 数据库名
const char user[] = "root"; // 用户名
const char passwd[] = "test123"; // 用户密码
int main()
{
//1、获取MySQL实例(相当于创建了一个MySQL句柄)
MYSQL* ms = mysql_init(nullptr);
//2、连接数据库
if(mysql_real_connect(ms, host, user, passwd, db, port, nullptr, 0) == nullptr) {
printf("数据库连接失败!\n");
return 1;
}
//设置连接的编码格式
mysql_set_character_set(ms, "utf8");
printf("数据库连接成功!\n");
//3. 访问数据库
//3.1 select 其实是最不好处理的!select sql执行完只是第一步,还需要对数据进一步解析
char sql[] = "select * from orderitems;";
int code = mysql_query(ms, sql);
if(code != 0){
printf("execute: %s failed\n", sql);
return 2;
}
printf("execute: %s success\n", sql);
//3.2 解析数据 -- 获取行号和列号
MYSQL_RES *result = mysql_store_result(ms);
int rows = mysql_num_rows(result);
int cols = mysql_num_fields(result);
printf("行数:%d,列数:%d\n", rows, cols);
//3.3 解析数据 -- 获取表中列名 -- 一般不用,仅仅是为了测试代码的完整性
MYSQL_FIELD *fields = mysql_fetch_fields(result);
for(int i = 0; i < cols; i++){
printf("%s\t", fields[i].name);
}
printf("\n");
//3.4 解析数据 -- 获取表中的数据 -- 重要
for(int i = 0; i < rows; i++){
MYSQL_ROW line = mysql_fetch_row(result); // 获取完整的一行记录(默认从前往后)
for(int j = 0; j < cols; j++){
printf("%s\t", line[j]); // 将一行记录内部的多列字符串依次打印
}
printf("\n");
}
mysql_free_result(result); // 释放内存空间
//4、关闭数据库连接
mysql_close(ms);
printf("数据库连接关闭成功!\n");
return 0;
}
#include <stdio.h>
#include <winsock.h>
#include <mysql.h>
const char host[] = "127.0.0.1"; // MySQL所在机器的ip
const int port = 0; // MySQL所在机器的端口
const char db[] = "test"; // 数据库名
const char user[] = "root"; // 用户名
const char passwd[] = "test123"; // 用户密码
// 查询表的内容
int select(MYSQL* ms)
{
//3.1 select 其实是最不好处理的!select sql执行完只是第一步,还需要对数据进一步解析
char sql[] = "select * from man;";
int code = mysql_query(ms, sql);
if(code != 0){
printf("execute: %s failed\n", sql);
return 2;
}
printf("execute: %s success\n", sql);
//3.2 解析数据 -- 获取行号和列号
MYSQL_RES *result = mysql_store_result(ms);
int rows = mysql_num_rows(result);
int cols = mysql_num_fields(result);
printf("行数:%d,列数:%d\n", rows, cols);
//3.3 解析数据 -- 获取表中列名 -- 一般不用,仅仅是为了测试代码的完整性
MYSQL_FIELD *fields = mysql_fetch_fields(result);
for(int i = 0; i < cols; i++){
printf("%s\t", fields[i].name);
}
printf("\n");
//3.4 解析数据 -- 获取表中的数据 -- 重要
for(int i = 0; i < rows; i++){
MYSQL_ROW line = mysql_fetch_row(result); // 获取完整的一行记录(默认从前往后)
for(int j = 0; j < cols; j++){
printf("%s\t", line[j]); // 将一行记录内部的多列字符串依次打印
}
printf("\n");
}
mysql_free_result(result); // 释放内存空间
return 0;
}
int main()
{
//1、获取MySQL实例(相当于创建了一个MySQL句柄)
MYSQL* ms = mysql_init(nullptr);
//2、连接数据库
if(mysql_real_connect(ms, host, user, passwd, db, port, nullptr, 0) == nullptr) {
printf("数据库连接失败!\n");
return 1;
}
//设置连接的编码格式
mysql_set_character_set(ms, "gb2312");
printf("数据库连接成功!\n");
//3. 访问数据库
select(ms);
// insert 操作
char sql_insert[] = "insert into man values (\'小刚\', 19);";
int res = mysql_query(ms, sql_insert);
if(res != 0){
printf("execute: %s failed\n", sql_insert);
return 2;
}
printf("execute: %s success\n", sql_insert);
select(ms);
//4、关闭数据库连接
mysql_close(ms);
printf("数据库连接关闭成功!\n");
return 0;
}
#include <stdio.h>
#include <winsock.h>
#include <mysql.h>
const char host[] = "127.0.0.1"; // MySQL所在机器的ip
const int port = 0; // MySQL所在机器的端口
const char db[] = "test"; // 数据库名
const char user[] = "root"; // 用户名
const char passwd[] = "test123"; // 用户密码
// 查询表的内容
int select(MYSQL* ms)
{
//3.1 select 其实是最不好处理的!select sql执行完只是第一步,还需要对数据进一步解析
char sql[] = "select * from man;";
int code = mysql_query(ms, sql);
if(code != 0){
printf("execute: %s failed\n", sql);
return 2;
}
printf("execute: %s success\n", sql);
//3.2 解析数据 -- 获取行号和列号
MYSQL_RES *result = mysql_store_result(ms);
int rows = mysql_num_rows(result);
int cols = mysql_num_fields(result);
printf("行数:%d,列数:%d\n", rows, cols);
//3.3 解析数据 -- 获取表中列名 -- 一般不用,仅仅是为了测试代码的完整性
MYSQL_FIELD *fields = mysql_fetch_fields(result);
for(int i = 0; i < cols; i++){
printf("%s\t", fields[i].name);
}
printf("\n");
//3.4 解析数据 -- 获取表中的数据 -- 重要
for(int i = 0; i < rows; i++){
MYSQL_ROW line = mysql_fetch_row(result); // 获取完整的一行记录(默认从前往后)
for(int j = 0; j < cols; j++){
printf("%s\t", line[j]); // 将一行记录内部的多列字符串依次打印
}
printf("\n");
}
mysql_free_result(result); // 释放内存空间
return 0;
}
int main()
{
//1、获取MySQL实例(相当于创建了一个MySQL句柄)
MYSQL* ms = mysql_init(nullptr);
//2、连接数据库
if(mysql_real_connect(ms, host, user, passwd, db, port, nullptr, 0) == nullptr) {
printf("数据库连接失败!\n");
return 1;
}
//设置连接的编码格式
mysql_set_character_set(ms, "gb2312");
printf("数据库连接成功!\n");
//3. 访问数据库
select(ms);
// delete 操作
char sql_delete[] = "delete from man where name=\'小刚\'";
int res = mysql_query(ms, sql_delete);
if(res != 0){
printf("execute: %s failed\n", sql_delete);
return 2;
}
printf("execute: %s success\n", sql_delete);
select(ms);
//4、关闭数据库连接
mysql_close(ms);
printf("数据库连接关闭成功!\n");
return 0;
}
#include <stdio.h>
#include <winsock.h>
#include <mysql.h>
const char host[] = "127.0.0.1"; // MySQL所在机器的ip
const int port = 0; // MySQL所在机器的端口
const char db[] = "test"; // 数据库名
const char user[] = "root"; // 用户名
const char passwd[] = "test123"; // 用户密码
// 查询表的内容
int select(MYSQL* ms)
{
//3.1 select 其实是最不好处理的!select sql执行完只是第一步,还需要对数据进一步解析
char sql[] = "select * from man;";
int code = mysql_query(ms, sql);
if(code != 0){
printf("execute: %s failed\n", sql);
return 2;
}
printf("execute: %s success\n", sql);
//3.2 解析数据 -- 获取行号和列号
MYSQL_RES *result = mysql_store_result(ms);
int rows = mysql_num_rows(result);
int cols = mysql_num_fields(result);
printf("行数:%d,列数:%d\n", rows, cols);
//3.3 解析数据 -- 获取表中列名 -- 一般不用,仅仅是为了测试代码的完整性
MYSQL_FIELD *fields = mysql_fetch_fields(result);
for(int i = 0; i < cols; i++){
printf("%s\t", fields[i].name);
}
printf("\n");
//3.4 解析数据 -- 获取表中的数据 -- 重要
for(int i = 0; i < rows; i++){
MYSQL_ROW line = mysql_fetch_row(result); // 获取完整的一行记录(默认从前往后)
for(int j = 0; j < cols; j++){
printf("%s\t", line[j]); // 将一行记录内部的多列字符串依次打印
}
printf("\n");
}
mysql_free_result(result); // 释放内存空间
return 0;
}
int main()
{
//1、获取MySQL实例(相当于创建了一个MySQL句柄)
MYSQL* ms = mysql_init(nullptr);
//2、连接数据库
if(mysql_real_connect(ms, host, user, passwd, db, port, nullptr, 0) == nullptr) {
printf("数据库连接失败!\n");
return 1;
}
//设置连接的编码格式
mysql_set_character_set(ms, "gb2312");
printf("数据库连接成功!\n");
//3. 访问数据库
select(ms);
// update 操作
char sql_update[] = "update man set age = 20 where name=\'小明\'";
int res = mysql_query(ms, sql_update);
if(res != 0){
printf("execute: %s failed\n", sql_update);
return 2;
}
printf("execute: %s success\n", sql_update);
select(ms);
//4、关闭数据库连接
mysql_close(ms);
printf("数据库连接关闭成功!\n");
return 0;
}
- 执行 update 操作:
- 执行 delete 操作:
- 执行 insert 操作:
- 执行 select 操作: