linux学习笔记(35)C语言连接mysql

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;
}
相关推荐
xlq223226 分钟前
30.进程池IPC
linux·运维·服务器
nuomigege21 分钟前
beagleboneblack刷入官方IOT镜像后无法运行nodered问题的处理
linux·运维·服务器
liangshanbo121536 分钟前
大模型 RAG 向量数据工程全链路架构笔记
笔记·架构
huaxiu51 小时前
ubuntu下应用打不开
linux·运维·ubuntu
罗罗攀1 小时前
PyTorch学习笔记|张量的广播和科学运算
人工智能·pytorch·笔记·python·学习
m0_683124791 小时前
Ubuntu服务设置开机自启
linux·运维·ubuntu
BestOrNothing_20151 小时前
(1)双系统中Ubuntu22.04启动盘制作与启动盘恢复全过程
linux·ubuntu·双系统·启动盘制作·启动盘恢复
AI成长日志1 小时前
【实用工具教程】Linux常用命令速查与实战场景:文件操作、进程管理与网络调试高频命令解析
linux·php
左左右右左右摇晃1 小时前
Java 笔记--OOM产生原因以及解决方法
java·笔记
落叶花开又一年1 小时前
检验检测机构资质认定远程评审工作程序
linux·运维·服务器