C语言连接MySQL(详细教程)
1. 安装开发库
# 切换到管理员
sudo su
# 安装MySQL开发库
apt install libmysqlclient-dev
# 验证安装
find /usr -name "mysql.h"
2. 核心API函数详解
连接流程需要的函数:
cpp
// 1. 初始化连接句柄
MYSQL *mysql_init(MYSQL *mysql);
// 2. 连接数据库
MYSQL *mysql_real_connect(
MYSQL *mysql, // 连接句柄
const char *host, // 主机地址:"localhost"或"127.0.0.1"
const char *user, // 用户名:"root"
const char *passwd, // 密码:"你的密码"
const char *db, // 数据库名:"testdb"
unsigned int port, // 端口号:3306或0(默认)
const char *unix_socket,// NULL
unsigned long clientflag // 0
);
// 3. 执行SQL语句
int mysql_query(MYSQL *mysql, const char *query);
// 4. 获取结果集
MYSQL_RES *mysql_store_result(MYSQL *mysql);
// 5. 获取行数
uint64_t mysql_num_rows(MYSQL_RES *result);
// 6. 获取列数
unsigned int mysql_num_fields(MYSQL_RES *result);
// 7. 逐行读取数据
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
// 8. 释放结果集
void mysql_free_result(MYSQL_RES *result);
// 9. 关闭连接
void mysql_close(MYSQL *mysql);
// 10. 错误处理
const char *mysql_error(MYSQL *mysql);
unsigned int mysql_errno(MYSQL *mysql);
3. 完整示例代码(带详细注释)
示例1:查询数据
cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>
int main() {
MYSQL mysql; // 定义MySQL连接对象
MYSQL_RES *res; // 结果集指针
MYSQL_ROW row; // 行数据指针
int fields; // 字段数
int rows; // 行数
// 1. 初始化连接句柄
printf("1. 初始化MySQL连接...\n");
if (mysql_init(&mysql) == NULL) {
printf("初始化失败: %s\n", mysql_error(&mysql));
return -1;
}
// 2. 连接数据库
printf("2. 连接数据库...\n");
if (mysql_real_connect(&mysql, "localhost", "root", "123456", "school", 0, NULL, 0) == NULL) {
printf("连接失败: %s\n", mysql_error(&mysql));
mysql_close(&mysql);
return -1;
}
printf("连接成功!\n");
// 3. 设置字符集(重要!避免中文乱码)
printf("3. 设置字符集...\n");
if (mysql_query(&mysql, "set names utf8") != 0) {
printf("设置字符集失败: %s\n", mysql_error(&mysql));
}
// 4. 执行查询语句
printf("4. 执行查询...\n");
char *sql = "SELECT id, name, age, gender, score FROM students";
if (mysql_query(&mysql, sql) != 0) {
printf("查询失败: %s\n", mysql_error(&mysql));
mysql_close(&mysql);
return -1;
}
// 5. 获取结果集
printf("5. 获取结果集...\n");
res = mysql_store_result(&mysql);
if (res == NULL) {
printf("获取结果集失败: %s\n", mysql_error(&mysql));
mysql_close(&mysql);
return -1;
}
// 6. 获取行数和列数
rows = mysql_num_rows(res);
fields = mysql_num_fields(res);
printf("查询结果: %d 行, %d 列\n\n", rows, fields);
// 7. 打印表头
MYSQL_FIELD *field;
printf("| ID | 姓名 | 年龄 | 性别 | 成绩 |\n");
printf("|----|------|------|------|------|\n");
// 8. 逐行读取并打印数据
while ((row = mysql_fetch_row(res)) != NULL) {
// 注意:row[i] 可能为NULL,需要判断
printf("| %s | %s | %s | %s | %s |\n",
row[0] ? row[0] : "NULL",
row[1] ? row[1] : "NULL",
row[2] ? row[2] : "NULL",
row[3] ? row[3] : "NULL",
row[4] ? row[4] : "NULL");
}
// 9. 释放资源
printf("\n9. 释放资源...\n");
mysql_free_result(res);
mysql_close(&mysql);
printf("程序结束!\n");
return 0;
}
编译命令:
gcc -o mysql_query mysql_query.c -lmysqlclient
./mysql_query
示例2:插入数据
cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>
int main() {
MYSQL mysql;
// 初始化并连接数据库
mysql_init(&mysql);
if (!mysql_real_connect(&mysql, "localhost", "root", "123456", "school", 0, NULL, 0)) {
printf("连接失败: %s\n", mysql_error(&mysql));
return -1;
}
// 设置字符集
mysql_query(&mysql, "set names utf8");
// 准备插入数据的SQL语句
char sql[256];
char name[] = "新学生";
int age = 19;
char gender[] = "男";
float score = 87.5;
// 构造SQL语句(注意:字符串需要引号)
sprintf(sql, "INSERT INTO students (name, age, gender, score) VALUES ('%s', %d, '%s', %.1f)",
name, age, gender, score);
printf("执行SQL: %s\n", sql);
// 执行插入
if (mysql_query(&mysql, sql) == 0) {
printf("插入成功!影响行数: %lld\n",
(long long)mysql_affected_rows(&mysql));
} else {
printf("插入失败: %s\n", mysql_error(&mysql));
}
mysql_close(&mysql);
return 0;
}
示例3:事务处理
cpp
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
// 转账函数:从from_id转amount金额到to_id
int transfer_money(MYSQL *mysql, int from_id, int to_id, double amount) {
// 开始事务
if (mysql_query(mysql, "START TRANSACTION") != 0) {
printf("开始事务失败: %s\n", mysql_error(mysql));
return -1;
}
// 扣款
char sql1[256];
sprintf(sql1, "UPDATE account SET balance = balance - %.2f WHERE id = %d", amount, from_id);
if (mysql_query(mysql, sql1) != 0) {
printf("扣款失败: %s\n", mysql_error(mysql));
mysql_query(mysql, "ROLLBACK");
return -1;
}
// 检查余额是否足够
sprintf(sql1, "SELECT balance FROM account WHERE id = %d", from_id);
mysql_query(mysql, sql1);
MYSQL_RES *res = mysql_store_result(mysql);
MYSQL_ROW row = mysql_fetch_row(res);
double balance = atof(row[0]);
mysql_free_result(res);
if (balance < 0) {
printf("余额不足!当前余额: %.2f\n", balance);
mysql_query(mysql, "ROLLBACK");
return -1;
}
// 收款
char sql2[256];
sprintf(sql2, "UPDATE account SET balance = balance + %.2f WHERE id = %d", amount, to_id);
if (mysql_query(mysql, sql2) != 0) {
printf("收款失败: %s\n", mysql_error(mysql));
mysql_query(mysql, "ROLLBACK");
return -1;
}
// 提交事务
if (mysql_query(mysql, "COMMIT") == 0) {
printf("转账成功!\n");
return 0;
} else {
printf("提交事务失败: %s\n", mysql_error(mysql));
mysql_query(mysql, "ROLLBACK");
return -1;
}
}
int main() {
MYSQL mysql;
mysql_init(&mysql);
if (!mysql_real_connect(&mysql, "localhost", "root", "123456", "testdb", 0, NULL, 0)) {
printf("连接失败: %s\n", mysql_error(&mysql));
return -1;
}
// 创建测试表
mysql_query(&mysql, "CREATE TABLE IF NOT EXISTS account ("
"id INT PRIMARY KEY, "
"name VARCHAR(50), "
"balance DECIMAL(10,2))");
// 插入测试数据
mysql_query(&mysql, "INSERT INTO account VALUES (1, '张三', 1000.00)");
mysql_query(&mysql, "INSERT INTO account VALUES (2, '李四', 500.00)");
// 执行转账:张三给李四转200元
transfer_money(&mysql, 1, 2, 200.00);
mysql_close(&mysql);
return 0;
}