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;
}
相关推荐
لا معنى له13 小时前
目标检测的内涵、发展和经典模型--学习笔记
人工智能·笔记·深度学习·学习·目标检测·机器学习
石像鬼₧魂石15 小时前
内网渗透靶场实操清单(基于 Vulhub+Metasploitable 2)
linux·windows·学习·ubuntu
flying robot16 小时前
centos7系统配置
笔记
橘子真甜~16 小时前
C/C++ Linux网络编程15 - 网络层IP协议
linux·网络·c++·网络协议·tcp/ip·计算机网络·网络层
醇氧17 小时前
org.jetbrains.annotations的@Nullable 学习
java·开发语言·学习·intellij-idea
拾贰_C17 小时前
【Linux | Windows | Terminal Command】 Linux---grep | Windows--- findstr
linux·运维·服务器
敲敲了个代码18 小时前
隐式类型转换:哈基米 == 猫 ? true :false
开发语言·前端·javascript·学习·面试·web
阿华hhh18 小时前
Linux系统编程(标准io)
linux·开发语言·c++
石像鬼₧魂石18 小时前
Kali Linux 网络端口深度扫描
linux·运维·网络
alengan19 小时前
linux上面写python3日志服务器
linux·运维·服务器