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;
}
相关推荐
小狗爱吃黄桃罐头15 分钟前
正点原子【第四期】Linux之驱动开发学习笔记-10.1 Linux 内核定时器实验
linux·驱动开发·学习
卡提西亚16 分钟前
一本通网站1122题:计算鞍点
c++·笔记·编程题·一本通
im_AMBER23 分钟前
Leetcode 47
数据结构·c++·笔记·学习·算法·leetcode
Kang强1 小时前
tcpdump 抓到 icmp 包,但是抓不到 tcp 包??
linux
BreezeJuvenile1 小时前
外设模块学习(17)——5V继电器模块(STM32)
stm32·单片机·嵌入式硬件·学习·5v继电器模块
demodashi6661 小时前
Linux下ag搜索命令详解
linux·运维·windows
一个数据大开发1 小时前
【零基础一站式指南】Conda 学习环境准备与 Jupyter/PyCharm 完全配置
学习·jupyter·conda
無识1 小时前
Linux-第四章web服务
linux·运维·服务器
一叶知秋yyds2 小时前
Centos 安装 Docker教程
linux·docker·centos
fie88892 小时前
在CentOS 7上集成cJSON库的方法
linux·运维·centos