当前位置: 首页 > news >正文

MySQL官方C/C++ 接口入门

MySQL提供了多种方式供C/C++程序访问数据库,最常用的是MySQL官方提供的C API(也称为MySQL Connector/C)。本指南将介绍如何使用这些接口进行基本的数据库操作。

一、准备工作

安装MySQL开发库

在开始之前,你需要安装MySQL客户端库和开发文件:

Ubuntu/Debian:

bash

sudo apt-get install libmysqlclient-dev

CentOS/RHEL:

bash

sudo yum install mysql-devel

macOS (使用Homebrew):

bash

brew install mysql-client

包含头文件和链接库

在C/C++程序中,需要包含MySQL头文件:

cpp

#include <mysql/mysql.h>

编译时需要链接MySQL客户端库:

bash

gcc -o program program.c `mysql_config --cflags --libs`
# 或者
g++ -o program program.cpp `mysql_config --cflags --libs`

二、基本使用流程

1. 建立连接

cpp

#include <iostream>
#include <mysql/mysql.h>
#include <stdio.h>int main() {MYSQL *conn;const char *server = "localhost";const char *user = "your_username";const char *password = "your_password";const char *database = "your_database";// 初始化连接句柄conn = mysql_init(NULL);// 连接到数据库if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) {fprintf(stderr, "%s\n", mysql_error(conn));mysql_close(conn);return 1;}std::cout << "Connected to database successfully!" << std::endl;// 执行数据库操作...// 关闭连接mysql_close(conn);return 0;
}

2. 执行查询

cpp

// 执行SQL查询
if (mysql_query(conn, "SELECT * FROM users")) {fprintf(stderr, "%s\n", mysql_error(conn));mysql_close(conn);return 1;
}// 获取结果集
MYSQL_RES *result = mysql_store_result(conn);
if (result == NULL) {fprintf(stderr, "%s\n", mysql_error(conn));mysql_close(conn);return 1;
}// 获取字段数量
int num_fields = mysql_num_fields(result);// 获取所有行
MYSQL_ROW row;
while ((row = mysql_fetch_row(result))) {// 处理每一行的数据for (int i = 0; i < num_fields; i++) {printf("%s ", row[i] ? row[i] : "NULL");}printf("\n");
}// 释放结果集
mysql_free_result(result);

3. 执行插入、更新和删除操作

cpp

// 插入数据
if (mysql_query(conn, "INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com')")) {fprintf(stderr, "INSERT error: %s\n", mysql_error(conn));
} else {std::cout << "Inserted successfully, affected rows: " << mysql_affected_rows(conn) << std::endl;
}// 更新数据
if (mysql_query(conn, "UPDATE users SET email='newemail@example.com' WHERE name='John Doe'")) {fprintf(stderr, "UPDATE error: %s\n", mysql_error(conn));
} else {std::cout << "Updated successfully, affected rows: " << mysql_affected_rows(conn) << std::endl;
}// 删除数据
if (mysql_query(conn, "DELETE FROM users WHERE name='John Doe'")) {fprintf(stderr, "DELETE error: %s\n", mysql_error(conn));
} else {std::cout << "Deleted successfully, affected rows: " << mysql_affected_rows(conn) << std::endl;
}

4. 使用预处理语句(防止SQL注入)

cpp

MYSQL_STMT *stmt;
MYSQL_BIND bind[2];
char name[50];
char email[100];// 创建预处理语句
stmt = mysql_stmt_init(conn);
if (mysql_stmt_prepare(stmt, "INSERT INTO users (name, email) VALUES (?, ?)", -1)) {fprintf(stderr, "Prepare error: %s\n", mysql_stmt_error(stmt));return 1;
}// 初始化绑定参数
memset(bind, 0, sizeof(bind));// 绑定name参数
bind[0].buffer_type = MYSQL_TYPE_STRING;
bind[0].buffer = name;
bind[0].buffer_length = sizeof(name);// 绑定email参数
bind[1].buffer_type = MYSQL_TYPE_STRING;
bind[1].buffer = email;
bind[1].buffer_length = sizeof(email);// 绑定参数到语句
if (mysql_stmt_bind_param(stmt, bind)) {fprintf(stderr, "Bind error: %s\n", mysql_stmt_error(stmt));return 1;
}// 设置参数值并执行
strcpy(name, "Jane Doe");
strcpy(email, "jane@example.com");if (mysql_stmt_execute(stmt)) {fprintf(stderr, "Execute error: %s\n", mysql_stmt_error(stmt));
} else {std::cout << "Prepared statement executed successfully!" << std::endl;
}// 关闭预处理语句
mysql_stmt_close(stmt);

错误处理

始终检查每个MySQL函数调用的返回值,并使用mysql_error()mysql_stmt_error()获取错误信息:

cpp

if (mysql_query(conn, "SELECT * FROM non_existent_table")) {fprintf(stderr, "Error: %s\n", mysql_error(conn));// 处理错误
}
class MySQLConnection : public MySQLBase {
public:MySQLConnection() : MySQLBase() {conn = mysql_init(nullptr);if (conn == nullptr) {throw std::runtime_error("无法初始化MySQL连接");}// 设置连接选项mysql_options(conn, MYSQL_OPT_RECONNECT, &reconnect);mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8mb4");}~MySQLConnection() {disconnect();}bool connect(const std::string& host, const std::string& user,const std::string& password, const std::string& database,unsigned int port = 3306, const char* unix_socket = nullptr,unsigned long client_flag = 0) {checkConnection();MYSQL* result = mysql_real_connect(conn, host.c_str(), user.c_str(),password.c_str(), database.c_str(),port, unix_socket, client_flag);if (result == nullptr) {unsigned int error_code = mysql_errno(conn);std::string error_msg = mysql_error(conn);// 根据错误代码进行特殊处理switch (error_code) {case CR_CONN_HOST_ERROR:throw MySQLException(error_code, mysql_sqlstate(conn),"无法连接到主机: " + host + " - " + error_msg);case CR_CONNECTION_ERROR:throw MySQLException(error_code, mysql_sqlstate(conn),"连接错误: " + error_msg);case CR_SERVER_GONE_ERROR:throw MySQLException(error_code, mysql_sqlstate(conn),"服务器连接已断开: " + error_msg);case CR_SERVER_LOST:throw MySQLException(error_code, mysql_sqlstate(conn),"服务器连接丢失: " + error_msg);case CR_ACCESS_DENIED_ERROR:throw MySQLException(error_code, mysql_sqlstate(conn),"访问被拒绝: " + user + "@" + host);default:throw MySQLException(error_code, mysql_sqlstate(conn),"连接失败: " + error_msg);}}// 设置字符集if (mysql_set_character_set(conn, "utf8mb4") != 0) {throw MySQLException(mysql_errno(conn), mysql_sqlstate(conn),"设置字符集失败: " + std::string(mysql_error(conn)));}return true;}void disconnect() {if (conn != nullptr) {mysql_close(conn);conn = nullptr;}}bool ping() {checkConnection();return mysql_ping(conn) == 0;}private:my_bool reconnect = 1; // 启用自动重连
};

三、UTF-8处理

设置客户端字符集为UTF-8

1. 连接后立即设置字符集

cpp

#include <iostream>
#include <mysql/mysql.h>
#include <cstring>int main() {MYSQL *conn = mysql_init(NULL);if (!mysql_real_connect(conn, "localhost", "username", "password", "testdb", 0, NULL, 0)) {std::cerr << "连接失败: " << mysql_error(conn) << std::endl;return 1;}// 设置字符集为UTF-8if (mysql_set_character_set(conn, "utf8mb4")) {std::cerr << "设置字符集失败: " << mysql_error(conn) << std::endl;mysql_close(conn);return 1;}std::cout << "字符集设置为: " << mysql_character_set_name(conn) << std::endl;mysql_close(conn);return 0;
}
2. 在连接选项中指定字符集

cpp

MYSQL *conn = mysql_init(NULL);// 设置连接选项
mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8mb4");
mysql_options(conn, MYSQL_INIT_COMMAND, "SET NAMES utf8mb4");if (!mysql_real_connect(conn, "localhost", "username", "password", "testdb", 0, NULL, 0)) {std::cerr << "连接失败: " << mysql_error(conn) << std::endl;return 1;
}

完整的UTF-8处理示例

#include <iostream>
#include <mysql/mysql.h>
#include <cstring>
#include <string>class MySQLUTF8Handler {
private:MYSQL *conn;public:MySQLUTF8Handler() : conn(nullptr) {}~MySQLUTF8Handler() {disconnect();}bool connect(const std::string& host, const std::string& user, const std::string& password, const std::string& database) {conn = mysql_init(nullptr);if (!conn) {std::cerr << "初始化MySQL失败" << std::endl;return false;}// 设置字符集选项mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8mb4");if (!mysql_real_connect(conn, host.c_str(), user.c_str(), password.c_str(), database.c_str(), 0, nullptr, 0)) {std::cerr << "连接失败: " << mysql_error(conn) << std::endl;return false;}// 确保字符集设置成功if (mysql_set_character_set(conn, "utf8mb4")) {std::cerr << "设置字符集失败: " << mysql_error(conn) << std::endl;return false;}std::cout << "成功连接到数据库,字符集: " << mysql_character_set_name(conn) << std::endl;return true;}void disconnect() {if (conn) {mysql_close(conn);conn = nullptr;}}bool createTable() {const char* query = "CREATE TABLE IF NOT EXISTS multilingual (""id INT AUTO_INCREMENT PRIMARY KEY, ""chinese_text VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, ""japanese_text VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, ""korean_text VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, ""russian_text VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci) ""ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";if (mysql_query(conn, query)) {std::cerr << "创建表失败: " << mysql_error(conn) << std::endl;return false;}return true;}bool insertMultilingualData(const std::string& chinese, const std::string& japanese,const std::string& korean, const std::string& russian) {// 使用预处理语句防止SQL注入并正确处理UTF-8MYSQL_STMT *stmt = mysql_stmt_init(conn);if (!stmt) {std::cerr << "初始化预处理语句失败" << std::endl;return false;}const char* query = "INSERT INTO multilingual (chinese_text, japanese_text, korean_text, russian_text) ""VALUES (?, ?, ?, ?)";if (mysql_stmt_prepare(stmt, query, strlen(query))) {std::cerr << "准备语句失败: " << mysql_stmt_error(stmt) << std::endl;mysql_stmt_close(stmt);return false;}MYSQL_BIND bind[4];memset(bind, 0, sizeof(bind));// 绑定中文参数bind[0].buffer_type = MYSQL_TYPE_STRING;bind[0].buffer = (void*)chinese.c_str();bind[0].buffer_length = chinese.length();bind[0].length = &bind[0].buffer_length;// 绑定日文参数bind[1].buffer_type = MYSQL_TYPE_STRING;bind[1].buffer = (void*)japanese.c_str();bind[1].buffer_length = japanese.length();bind[1].length = &bind[1].buffer_length;// 绑定韩文参数bind[2].buffer_type = MYSQL_TYPE_STRING;bind[2].buffer = (void*)korean.c_str();bind[2].buffer_length = korean.length();bind[2].length = &bind[2].buffer_length;// 绑定俄文参数bind[3].buffer_type = MYSQL_TYPE_STRING;bind[3].buffer = (void*)russian.c_str();bind[3].buffer_length = russian.length();bind[3].length = &bind[3].buffer_length;if (mysql_stmt_bind_param(stmt, bind)) {std::cerr << "绑定参数失败: " << mysql_stmt_error(stmt) << std::endl;mysql_stmt_close(stmt);return false;}if (mysql_stmt_execute(stmt)) {std::cerr << "执行语句失败: " << mysql_stmt_error(stmt) << std::endl;mysql_stmt_close(stmt);return false;}mysql_stmt_close(stmt);return true;}void queryAndDisplayData() {const char* query = "SELECT * FROM multilingual";if (mysql_query(conn, query)) {std::cerr << "查询失败: " << mysql_error(conn) << std::endl;return;}MYSQL_RES *result = mysql_store_result(conn);if (!result) {std::cerr << "获取结果失败: " << mysql_error(conn) << std::endl;return;}int num_fields = mysql_num_fields(result);MYSQL_ROW row;std::cout << "\n查询结果:" << std::endl;std::cout << "==========================================" << std::endl;while ((row = mysql_fetch_row(result))) {std::cout << "ID: " << (row[0] ? row[0] : "NULL") << std::endl;std::cout << "中文: " << (row[1] ? row[1] : "NULL") << std::endl;std::cout << "日文: " << (row[2] ? row[2] : "NULL") << std::endl;std::cout << "韩文: " << (row[3] ? row[3] : "NULL") << std::endl;std::cout << "俄文: " << (row[4] ? row[4
http://www.dtcms.com/a/348413.html

相关文章:

  • 从栈到堆:深入理解C语言静态与动态链表的创建与管理
  • 利旧小天才儿童电话手表实现“一键寻车”功能
  • 线程整理文档
  • 使用UE5开发《红色警戒3》类战略养成游戏的硬件配置指南
  • 【Spring Cloud 微服务】3.智能路由器——深入理解与配置负载均衡
  • MySQL的更新语句执行过程涉及了哪些文件的写入,衍生了redo、undo、二进制日志在什么时候进行写入
  • 从 JUnit 深入理解 Java 注解与反射机制
  • HarmonyOS NEXT系列之元服务框架ASCF
  • 波兰密码破译机bomba:二战密码战的隐形功臣
  • 深入OpenHarmony OTA硬核升级
  • ComfyUI ZLUDA AMD conda 使用遇到的问题
  • stm32温控大棚测控系统(CO2+温湿度+光照)+仿真
  • Docker 容器(一)
  • 【ansible】5.在受管主机部署文件和Jinja2模板
  • 信誉代币的发行和管理机制是怎样的?
  • 基于角色的访问控制(RBAC)研究与Go语言实现
  • overleaf关于给参考文献添加DOI链接的问题
  • B站视频字幕提取工具
  • 当GitHub“断网”:从应急到终极方案,手把手搭建永不宕机的代码协作体系
  • 鸿蒙 ArkTS 开发:Number、Boolean、String 三种核心基本数据类型详解(附实战案例)
  • 从 Unity UGUI 到 Unreal UMG 的无缝迁移:UMG 基础与 UI 控件布局
  • Java的数字计算
  • pycharm的matplotlib不显示动图问题的解决
  • Python核心技术开发指南(004)——配置PyCharm
  • Flink直接缓冲存储器异常解析与解决方案
  • 力扣155.最小栈
  • 嵌入式知识篇---32GUI
  • 神经网络|(十四)概率论基础知识-协方差和方差
  • 使用 Golang 的 Gin 框架实现一周极限编程计划:全网 AIGC 项目热点追踪应用
  • 自然语言处理——06 迁移学习(下)