tencent cloud

TDSQL Boundless

产品动态
产品简介
产品概述
应用场景
产品架构
实例类型
兼容性说明
使用规范建议
自研内核
内核概述
内核版本更新动态
功能类特性
性能类特性
产品计费
计费概述
购买方式
价格详情
续费说明
欠费说明
退费说明
快速入门
创建实例
连接实例
用户指南
数据迁移
数据同步/订阅
实例管理
参数配置
账号管理
安全组
备份与恢复
数据库审计
标签管理
实践教程
Online DDL 的技术演进与使用实践
锁机制解析与问题排查实践
数据智能调度及相关性能优化实践
TDSQL Boundless 选型指南与实践教程
开发指南
开发指南(MySQL 兼容模式)
开发指南(HBase 兼容模式)
性能调优
性能调优概述
SQL 调优
DDL 调优
性能白皮书
性能概述
TPC-C 测试
Sysbench 测试
API 文档
History
Introduction
API Category
Making API Requests
Instance APIs
Security Group APIs
Task APIs
Backup APIs
Rollback APIs
Parameter APIs
Database APIs
Data Types
Error Codes
通用参考
系统原理
SQL 参考
数据库参数说明
TPC-H 基准测试数据模型参考
错误码信息
安全与合规
常见问题
服务协议
服务等级协议
服务条款
隐私政策
数据处理和安全协议
联系我们
词汇表

C

PDF
聚焦模式
字号
最后更新时间: 2026-04-03 16:07:54
MySQL Connector/C 通常被称为 MySQL C API,它提供了一组 C 语言的函数和数据结构,允许开发人员使用 C/C++ 语言来连接、查询和管理数据库。这个 API 允许开发人员直接在其 C/C++ 应用程序中使用兼容 MySQL 协议的数据库。
本文将介绍如何使用 MySQL Connector/C (libmysqlclient) 驱动和 TDSQL Boundless 数据库构建一个应用程序,实现创建表、插入数据和查询数据等基本操作。

前提条件

在安装使用 MySQL Connector/C (libmysqlclient) 前请确保设置了基本的数据库开发环境,要求如下:
GCC 版本为3.4.6及以上,推荐使用4.8.5版本。
CMake 版本为2.8.12及以上。
您已部署 TDSQL Boundless 数据库并创建了相应的数据库实例。

操作步骤

1. 获取 TDSQL Boundless 数据库连接信息。
2. 安装 MySQL Connector/C 驱动。
3. 编写应用程序。
4. 编译应用程序。
5. 运行应用程序。

步骤一:获取数据库连接串

mysql -h$host -P$port -u$user_name -p$password -D$database_name
参数说明:
参数
说明
$host
TDSQL Boundless 数据库连接 IP 地址或域名及端口(默认为 3306)。
OLTP 类访问地址:对等节点 VIP 地址及端口号可登录控制台,通过实例详情页面,在基本信息区域,内网地址字段获取对等节点 VIP,内网端口字段获取对等节点 Port。
$port
$user_name
数据库连接账户用户名及密码,详细请参见 创建账号
$password
$database_name
需要访问的数据库名称。
注意:
连接数据库的用户需要拥有该数据库的 CREATEINSERTDROPSELECT 权限。
示例如下:
mysql -h192.168.1.100 -P3306 -utest_user -p****** -Dtest_db

步骤二:安装 MySQL Connector/C 驱动

根据您的操作系统选择相应的安装命令:
## 在 Ubuntu/Debian 系统上请使用下面的代码进行安装:
sudo apt-get update
sudo apt-get install libmysqlclient-dev

## 在 CentOS/RHEL 系统上请使用下面的代码进行安装:
sudo yum install mysql-devel

## 确认是否安装成功
mysql_config --version
如果安装成功,mysql_config --version 命令将输出已安装的 MySQL 客户端库版本号。

步骤三:编写应用程序

打开你的文本编辑器,在文本编辑器中编辑示例 test.c 文件并保存,代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>

int main() {
MYSQL *conn = mysql_init(NULL); // 初始化 MySQL 连接

if (conn == NULL) {
fprintf(stderr, "mysql_init() failed\\n");
return 1;
}

// 连接到 TDSQL Boundless 数据库服务器
// 请将以下参数替换为实际的连接信息
if (mysql_real_connect(conn, "host", "user", "passwd", "db", 3306, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() failed: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}

printf("成功连接到 TDSQL Boundless 数据库!\\n");

// 设置字符集为 utf8mb4
if (mysql_set_character_set(conn, "utf8mb4") != 0) {
fprintf(stderr, "设置字符集失败: %s\\n", mysql_error(conn));
}

// 创建用户表
if (mysql_query(conn, "CREATE TABLE IF NOT EXISTS users (id INT AUTO_INCREMENT, name VARCHAR(255), email VARCHAR(255), PRIMARY KEY(id))") != 0) {
fprintf(stderr, "创建表失败: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}
printf("表创建成功!\\n");

// 插入数据
if (mysql_query(conn, "INSERT INTO users (name, email) VALUES ('小明', 'xiaoming@example.com')") != 0) {
fprintf(stderr, "插入数据失败: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}
printf("数据插入成功!\\n");

// 查询数据
if (mysql_query(conn, "SELECT * FROM users") == 0) {
MYSQL_RES *result = mysql_store_result(conn);
if (result != NULL) {
int num_fields = mysql_num_fields(result);
MYSQL_ROW row;
printf("\\n查询结果:\\n");
printf("----------------------------------------\\n");
while ((row = mysql_fetch_row(result))) {
for (int i = 0; i < num_fields; i++) {
printf("%s ", row[i] ? row[i] : "NULL");
}
printf("\\n");
}
printf("----------------------------------------\\n");
printf("共 %lu 条记录\\n", (unsigned long)mysql_num_rows(result));
mysql_free_result(result);
} else {
fprintf(stderr, "获取结果集失败: %s\\n", mysql_error(conn));
}
} else {
fprintf(stderr, "查询数据失败: %s\\n", mysql_error(conn));
}

mysql_close(conn); // 关闭连接
printf("数据库连接已关闭。\\n");
return 0;
}
根据 步骤一:获取数据库连接信息 中的信息修改项目文件 test.c 中的数据库连接信息。
在 Linux 环境下,可以使用 vi test.c 或者 vim test.c 命令编辑 test.c 文件,修改文件中的数据库连接信息,确保与实际情况相符。
test.c 文件中的数据库连接信息示例如下:
// 这部分连接信息需要修改为你所获取到连接串的真实信息,示例如下
if (mysql_real_connect(conn, "192.168.1.100", "test_user", "your_password", "test_db", 3306, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() failed: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}

步骤四:编译应用程序

代码编辑完成后,可以通过如下命令进行编译。
gcc -o test test.c `mysql_config --cflags --libs`
或者手动指定头文件和库路径:
gcc -o test test.c -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient
编译成功后,会生成可执行文件 test

步骤五:运行应用程序

通过如下命令运行应用程序。
./test
输出结果如下,说明数据库连接成功,示例语句正确执行:
成功连接到 TDSQL Boundless 数据库!
表创建成功!
数据插入成功!

查询结果:
----------------------------------------
1 小明 xiaoming@example.com
----------------------------------------
1 条记录

测试表已清理。
数据库连接已关闭。

更多示例

示例1:使用预处理语句插入数据

预处理语句可以有效防止 SQL 注入,并提高重复执行相同 SQL 语句的性能。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>

int main() {
MYSQL *conn = mysql_init(NULL);
MYSQL_STMT *stmt;
MYSQL_BIND bind[2];
char name[64] = "张三";
char email[128] = "zhangsan@example.com";
unsigned long name_length;
unsigned long email_length;

if (conn == NULL) {
fprintf(stderr, "mysql_init() failed\\n");
return 1;
}

// 连接到 TDSQL Boundless 数据库
if (mysql_real_connect(conn, "host", "user", "passwd", "db", 3306, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() failed: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}

// 设置字符集
mysql_set_character_set(conn, "utf8mb4");

// 确保表存在
mysql_query(conn, "CREATE TABLE IF NOT EXISTS users (id INT AUTO_INCREMENT, name VARCHAR(255), email VARCHAR(255), PRIMARY KEY(id))");

// 初始化预处理语句
stmt = mysql_stmt_init(conn);
if (stmt == NULL) {
fprintf(stderr, "mysql_stmt_init() failed\\n");
mysql_close(conn);
return 1;
}

// 准备 SQL 语句
const char *sql = "INSERT INTO users (name, email) VALUES (?, ?)";
if (mysql_stmt_prepare(stmt, sql, strlen(sql))) {
fprintf(stderr, "mysql_stmt_prepare() failed: %s\\n", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
mysql_close(conn);
return 1;
}

// 绑定参数
memset(bind, 0, sizeof(bind));

// 参数 1: name
name_length = strlen(name);
bind[0].buffer_type = MYSQL_TYPE_STRING;
bind[0].buffer = name;
bind[0].buffer_length = sizeof(name);
bind[0].length = &name_length;

// 参数 2: email
email_length = strlen(email);
bind[1].buffer_type = MYSQL_TYPE_STRING;
bind[1].buffer = email;
bind[1].buffer_length = sizeof(email);
bind[1].length = &email_length;

if (mysql_stmt_bind_param(stmt, bind)) {
fprintf(stderr, "mysql_stmt_bind_param() failed: %s\\n", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
mysql_close(conn);
return 1;
}

// 执行预处理语句
if (mysql_stmt_execute(stmt)) {
fprintf(stderr, "mysql_stmt_execute() failed: %s\\n", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
mysql_close(conn);
return 1;
}

printf("预处理语句执行成功!插入 ID: %lu\\n", (unsigned long)mysql_stmt_insert_id(stmt));

mysql_stmt_close(stmt);
mysql_close(conn);
return 0;
}

示例2:事务处理

事务可以确保一组数据库操作要么全部成功,要么全部失败。
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>

int main() {
MYSQL *conn = mysql_init(NULL);
int success = 1;

if (conn == NULL) {
fprintf(stderr, "mysql_init() failed\\n");
return 1;
}

// 连接到 TDSQL Boundless 数据库
if (mysql_real_connect(conn, "host", "user", "passwd", "db", 3306, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() failed: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}

mysql_set_character_set(conn, "utf8mb4");

// 关闭自动提交,开始事务
if (mysql_autocommit(conn, 0)) {
fprintf(stderr, "关闭自动提交失败: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}

printf("事务开始...\\n");

// 执行第一条 SQL
if (mysql_query(conn, "UPDATE accounts SET balance = balance - 100 WHERE user_id = 1")) {
fprintf(stderr, "SQL 1 执行失败: %s\\n", mysql_error(conn));
success = 0;
}

// 执行第二条 SQL
if (success && mysql_query(conn, "UPDATE accounts SET balance = balance + 100 WHERE user_id = 2")) {
fprintf(stderr, "SQL 2 执行失败: %s\\n", mysql_error(conn));
success = 0;
}

if (success) {
// 提交事务
if (mysql_commit(conn)) {
fprintf(stderr, "提交事务失败: %s\\n", mysql_error(conn));
} else {
printf("事务提交成功!\\n");
}
} else {
// 回滚事务
if (mysql_rollback(conn)) {
fprintf(stderr, "回滚事务失败: %s\\n", mysql_error(conn));
} else {
printf("事务已回滚\\n");
}
}

// 恢复自动提交
mysql_autocommit(conn, 1);

mysql_close(conn);
return 0;
}

示例3:批量查询与结果遍历

#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>

int main() {
MYSQL *conn = mysql_init(NULL);
MYSQL_RES *result;
MYSQL_ROW row;
MYSQL_FIELD *fields;
unsigned int num_fields;
unsigned int i;

if (conn == NULL) {
fprintf(stderr, "mysql_init() failed\\n");
return 1;
}

// 连接到 TDSQL Boundless 数据库
if (mysql_real_connect(conn, "host", "user", "passwd", "db", 3306, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() failed: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}

mysql_set_character_set(conn, "utf8mb4");

// 执行查询
if (mysql_query(conn, "SELECT id, name, email FROM users ORDER BY id DESC LIMIT 100")) {
fprintf(stderr, "查询失败: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}

// 获取结果集
result = mysql_store_result(conn);
if (result == NULL) {
fprintf(stderr, "获取结果集失败: %s\\n", mysql_error(conn));
mysql_close(conn);
return 1;
}

// 获取字段数量和字段信息
num_fields = mysql_num_fields(result);
fields = mysql_fetch_fields(result);

// 打印列名
printf("\\n");
for (i = 0; i < num_fields; i++) {
printf("%-20s", fields[i].name);
}
printf("\\n");
// 打印分隔线
for (i = 0; i < num_fields; i++) {
printf("--------------------");
}
printf("\\n");

// 遍历结果集
while ((row = mysql_fetch_row(result)) != NULL) {
for (i = 0; i < num_fields; i++) {
printf("%-20s", row[i] ? row[i] : "NULL");
}
printf("\\n");
}

printf("\\n共 %lu 行数据\\n", (unsigned long)mysql_num_rows(result));

// 释放结果集
mysql_free_result(result);

mysql_close(conn);
return 0;
}

常用 API 参考

函数
说明
mysql_init()
初始化 MySQL 连接句柄
mysql_real_connect()
连接到数据库服务器
mysql_close()
关闭数据库连接
mysql_query()
执行 SQL 语句
mysql_store_result()
获取完整结果集
mysql_use_result()
逐行获取结果集
mysql_fetch_row()
获取下一行数据
mysql_num_rows()
获取结果集行数
mysql_num_fields()
获取结果集列数
mysql_fetch_fields()
获取字段信息
mysql_affected_rows()
获取受影响的行数
mysql_free_result()
释放结果集
mysql_error()
获取错误信息
mysql_errno()
获取错误码
mysql_set_character_set()
设置字符集
mysql_autocommit()
设置自动提交模式
mysql_commit()
提交事务
mysql_rollback()
回滚事务
mysql_stmt_init()
初始化预处理语句
mysql_stmt_prepare()
准备预处理语句
mysql_stmt_bind_param()
绑定预处理语句参数
mysql_stmt_execute()
执行预处理语句
mysql_stmt_close()
关闭预处理语句

常见问题

1. 编译时找不到 mysql.h 头文件

问题fatal error: mysql/mysql.h: No such file or directory
解决方案:确保已安装 MySQL 开发库,并使用正确的编译参数:
# 安装开发库
sudo apt-get install libmysqlclient-dev # Ubuntu/Debian
sudo yum install mysql-devel # CentOS/RHEL

# 使用 mysql_config 获取正确的编译参数
gcc -o test test.c `mysql_config --cflags --libs`

2. 运行时找不到 libmysqlclient.so

问题error while loading shared libraries: libmysqlclient.so
解决方案
# 方法1:添加库路径到环境变量
export LD_LIBRARY_PATH=/usr/lib/mysql:$LD_LIBRARY_PATH

# 方法2:更新动态链接库缓存
sudo ldconfig

3. 中文显示乱码

问题:查询结果中文显示为乱码
解决方案:连接后设置字符集为 utf8mb4
mysql_set_character_set(conn, "utf8mb4");

4. 连接超时

问题:连接数据库时超时
解决方案:在连接前设置超时参数:
unsigned int timeout = 30;
mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);

参考资料

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈