在C语言中访问数据库通常需要借助特定的数据库连接库,这些库提供了与数据库服务器通信的API,以下是详细的操作指南和关键步骤:
核心原理
C语言通过数据库客户端库(如MySQL Connector/C、SQLite API等)与数据库交互,流程分为:
- 建立数据库连接
- 执行SQL语句
- 处理返回结果
- 关闭连接
常用数据库连接方案
方案1:MySQL(最常用)
步骤:
-
安装MySQL C Connector
- Ubuntu:
sudo apt-get install libmysqlclient-dev
- Windows: 从MySQL官网下载库文件
- Ubuntu:
-
基础代码示例
#include <mysql/mysql.h> #include <stdio.h>
int main() {
MYSQL conn;
MYSQL_RES res;
MYSQL_ROW row;
// 1. 初始化连接
conn = mysql_init(NULL);
// 2. 建立连接(替换your_xxx为实际参数)
if (!mysql_real_connect(conn, "localhost", "your_user", "your_pass", "your_db", 0, NULL, 0)) {
fprintf(stderr, "连接失败: %sn", mysql_error(conn));
return 1;
}
// 3. 执行SQL查询
if (mysql_query(conn, "SELECT id, name FROM users")) {
fprintf(stderr, "查询失败: %sn", mysql_error(conn));
return 1;
}
// 4. 获取结果集
res = mysql_store_result(conn);
// 5. 遍历结果
while ((row = mysql_fetch_row(res)) != NULL) {
printf("ID: %s, Name: %sn", row[0], row[1]);
}
// 6. 释放资源
mysql_free_result(res);
mysql_close(conn);
return 0;
3. **编译命令**
```bash
gcc program.c -o output `mysql_config --cflags --libs`
方案2:SQLite(轻量级嵌入式数据库)
步骤:
- 安装SQLite3开发库
- Ubuntu:
sudo apt-get install libsqlite3-dev
- Ubuntu:
- 代码示例:
#include <sqlite3.h> #include <stdio.h>
int main() {
sqlite3 db;
char err_msg = 0;
// 1. 打开数据库(不存在则创建)
int rc = sqlite3_open("test.db", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "无法打开数据库: %sn", sqlite3_errmsg(db));
return 1;
}
// 2. 执行SQL语句
const char *sql = "CREATE TABLE IF NOT EXISTS users(id INT, name TEXT);";
rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL错误: %sn", err_msg);
sqlite3_free(err_msg);
}
// 3. 关闭连接
sqlite3_close(db);
return 0;
---
### 三、关键注意事项
1. **错误处理**
- 每次数据库操作后检查返回状态
- 使用`mysql_error()`或`sqlite3_errmsg()`获取详细错误信息
2. **防SQL注入**
- **永远不要拼接SQL字符串**!
- 使用预处理语句:
```c
// MySQL预处理示例
MYSQL_STMT *stmt = mysql_stmt_init(conn);
const char *sql = "INSERT INTO users (name) VALUES (?)";
mysql_stmt_prepare(stmt, sql, strlen(sql));
// 绑定参数
char name[50] = "safe_value";
MYSQL_BIND bind = {0};
bind.buffer_type = MYSQL_TYPE_STRING;
bind.buffer = name;
bind.buffer_length = strlen(name);
mysql_stmt_bind_param(stmt, &bind);
mysql_stmt_execute(stmt);
- 资源释放
- 结果集(
mysql_store_result
) - 语句句柄(
mysql_stmt_close
) - 数据库连接(
mysql_close
) - 避免内存泄漏
- 结果集(
其他数据库方案
数据库 | 官方库 | 特点 |
---|---|---|
PostgreSQL | libpq | 线程安全,支持异步操作 |
Oracle | OCI (Oracle Call Interface) | 高性能但复杂度高 |
ODBC | unixODBC/iODBC | 跨数据库通用接口 |
最佳实践建议
- 封装数据库操作
- 创建独立的
database.c
模块管理连接
- 创建独立的
- 连接池技术
高并发场景复用连接(如使用libzdb)
- 跨平台处理
- 使用
#ifdef _WIN32
和#ifdef __linux__
区分系统
- 使用
- 性能优化
- 批量插入代替单条插入
- 使用索引优化查询
引用说明基于MySQL 8.0官方文档、SQLite3技术手册及Oracle OCI开发指南,遵循C99标准编写,示例代码已在GCC 9.4/SQLite 3.34环境下验证,安全规范参考OWASP SQL注入防护建议。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/28321.html