当前位置: 首页 > 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.xdnf.cn/news/1357417.html

相关文章:

  • Ubuntu24.04 安装 Zabbix
  • ComfyUI ZLUDA AMD conda 使用遇到的问题
  • rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(十五)网格布局
  • 【229页PPT】某大型制药集团企业数字化转型SAP蓝图设计解决方案(附下载方式)
  • 目标检测数据集 第006期-基于yolo标注格式的汽车事故检测数据集(含免费分享)
  • 网络协议UDP、TCP
  • 管道符在渗透测试与网络安全中的全面应用指南
  • 【信息安全】英飞凌TC3xx安全调试口功能实现(调试口保护)
  • OSG库子动态库和插件等文件介绍
  • AlmaLinux 上 Python 3.6 切换到 Python 3.11
  • 从 JUnit 深入理解 Java 注解与反射机制
  • Flink元空间异常深度解析:从原理到实战调优指南
  • 数字防线:现代企业网络安全运维实战指南
  • Maven项目中settings.xml终极优化指南
  • 得物25年春招-安卓部分笔试题1
  • Flink 实时加购数据“维表补全”实战:从 Kafka 到 HBase 再到 Redis 的完整链路
  • GaussDB 数据库架构师修炼(十八) SQL引擎-分布式计划
  • vimware unbuntu18.04 安装之后,没有网络解决方案
  • AI与SEO关键词协同优化
  • 【小程序-慕尚花坊02】网络请求封装和注意事项
  • 个人搭建小网站教程(云服务器Ubuntu版本)
  • 不知道Pycharm怎么安装?Pycharm安装教程(附安装包)
  • MySQL數據庫開發教學(二) 核心概念、重要指令
  • GaussDB 数据库架构师修炼(十八) SQL引擎-统计信息
  • 请求上下文对象RequestContextHolder
  • LIANA | part2 results部分
  • 【贪心算法】day1
  • spring源码之事务篇(事务管理器整个流程)
  • JAVA限流方法
  • PAT 1081 Rational Sum