linux学习笔记(35)C语言连接mysql
C语言连接MySQL(详细教程)
1. 安装开发库
# 切换到管理员
sudo su# 安装MySQL开发库
apt install libmysqlclient-dev# 验证安装
find /usr -name "mysql.h"
2. 核心API函数详解
连接流程需要的函数:
// 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,// NULLunsigned 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:查询数据
#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:插入数据
#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:事务处理
#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;
}