上一篇
"老张,市场部的销售数据能导出来发我一份吗?"小王第3次推开技术部的门,技术主管老张扶了扶眼镜,心想:"这周已经处理了20多次类似请求,得想个办法..."
在现代办公环境中,局域网内的数据共享需求无处不在,本文将带你用C语言这把"瑞士军刀",在局域网环境下优雅地访问数据库,告别手动导数据的石器时代。
开发环境配置:
必要库文件:
#include <mysql/mysql.h> // MySQL C API #include <stdio.h> #include <string.h>
安装MySQL C连接器(以Ubuntu为例):
sudo apt install libmysqlclient-dev
MYSQL *conn; const char *server = "192.168.1.100"; // 数据库服务器内网IP const char *user = "app_user"; const char *password = "SafeP@ss123"; const char *database = "company_db"; int main() { conn = mysql_init(NULL); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { fprintf(stderr, "连接失败: %s\n", mysql_error(conn)); return 1; } printf("成功连接到局域网数据库!\n"); // ...后续操作 mysql_close(conn); return 0; }
关键参数说明:
:端口号
void query_employee() { if (mysql_query(conn, "SELECT id, name FROM employees WHERE dept='sales'")) { fprintf(stderr, "查询失败: %s\n", mysql_error(conn)); return; } MYSQL_RES *result = mysql_store_result(conn); if (result == NULL) { fprintf(stderr, "获取结果集失败\n"); return; } 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); }
void add_employee(const char *name, int age) { char query[256]; snprintf(query, sizeof(query), "INSERT INTO employees(name, age) VALUES('%s', %d)", name, age); if (mysql_query(conn, query)) { fprintf(stderr, "插入失败: %s\n", mysql_error(conn)); } else { printf("新增员工成功,ID: %lu\n", mysql_insert_id(conn)); } }
void update_salary(int emp_id, float new_salary) { char query[128]; snprintf(query, sizeof(query), "UPDATE salaries SET amount=%.2f WHERE emp_id=%d", new_salary, emp_id); if (mysql_query(conn, query)) { fprintf(stderr, "更新失败: %s\n", mysql_error(conn)); } else { printf("影响行数: %lu\n", mysql_affected_rows(conn)); } }
void remove_department(int dept_id) { char query[64]; snprintf(query, sizeof(query), "DELETE FROM departments WHERE id=%d", dept_id); mysql_query(conn, "START TRANSACTION"); if (mysql_query(conn, query)) { mysql_query(conn, "ROLLBACK"); fprintf(stderr, "删除失败: %s\n", mysql_error(conn)); } else { mysql_query(conn, "COMMIT"); printf("部门已删除\n"); } }
// 初始化连接池 MYSQL *conn_pool[5]; for(int i=0; i<5; i++) { conn_pool[i] = mysql_init(NULL); mysql_real_connect(conn_pool[i], server, user, password, database, 0, NULL, 0); }
// 使用时轮询获取连接 MYSQL *get_connection() { static int index = 0; return conn_pool[(index++) % 5]; }
2. **批量操作减少网络往返**:
```c
void batch_insert() {
mysql_query(conn, "INSERT INTO log_entries(entry) VALUES ('启动批量模式')");
if (mysql_query(conn, "START TRANSACTION")) {
// 错误处理
}
// 执行多个INSERT语句...
if(所有操作成功) {
mysql_query(conn, "COMMIT");
} else {
mysql_query(conn, "ROLLBACK");
}
}
本地缓存策略:
// 对频繁访问但不常变的数据进行缓存 void get_department_list() { static time_t last_update = 0; static char cache[1024]; if(time(NULL) - last_update < 3600) { // 1小时缓存 printf("来自缓存: %s\n", cache); return; } // ...数据库查询 last_update = time(NULL); strncpy(cache, query_result, sizeof(cache)); }
参数化查询防注入:
void safe_query(const char *username) { MYSQL_STMT *stmt = mysql_stmt_init(conn); const char *query = "SELECT * FROM users WHERE name=?"; mysql_stmt_prepare(stmt, query, strlen(query)); MYSQL_BIND bind; memset(&bind, 0, sizeof(bind)); bind.buffer_type = MYSQL_TYPE_STRING; bind.buffer = (char *)username; bind.buffer_length = strlen(username); mysql_stmt_bind_param(stmt, &bind); mysql_stmt_execute(stmt); // ...处理结果 mysql_stmt_close(stmt); }
局域网安全配置:
完整错误处理示例:
void handle_database_error(MYSQL *conn) { unsigned int err_no = mysql_errno(conn); const char *err_msg = mysql_error(conn); switch(err_no) { case 2003: // 连接失败 printf("检查网络连接,服务器是否在线?\n"); break; case 1045: // 认证失败 printf("账号密码错误或权限不足\n"); break; case 1146: // 表不存在 printf("表名拼写错误或数据库结构已变更\n"); break; default: printf("错误代码 %d: %s\n", err_no, err_msg); } // 记录到日志文件 FILE *log = fopen("db_error.log", "a"); if(log) { fprintf(log, "[%s] 错误 %d: %s\n", get_current_time(), err_no, err_msg); fclose(log); } }
网络延迟检测:
void check_response_time() { struct timeval start, end; gettimeofday(&start, NULL); mysql_query(conn, "SELECT 1"); // 简单ping测试 gettimeofday(&end, NULL); long seconds = end.tv_sec - start.tv_sec; long micros = ((seconds * 1000000) + end.tv_usec) - start.tv_usec; printf("数据库响应时间: %.2f 毫秒\n", (float)micros/1000); }
#include <pthread.h> pthread_mutex_t db_mutex = PTHREAD_MUTEX_INITIALIZER; void* thread_query(void *arg) { pthread_mutex_lock(&db_mutex); // 执行数据库操作 if (mysql_query(conn, "SELECT * FROM large_table LIMIT 1000")) { // 错误处理 } pthread_mutex_unlock(&db_mutex); return NULL; } int main() { pthread_t threads[4]; for(int i=0; i<4; i++) { pthread_create(&threads[i], NULL, thread_query, NULL); } for(int i=0; i<4; i++) { pthread_join(threads[i], NULL); } mysql_close(conn); return 0; }
通过本文介绍的方法,技术部老张成功开发了一个内网数据服务系统,现在市场部的小王只需在办公电脑上运行一个简单的客户端程序,就能实时获取所需数据,再也不用频繁敲门了。
在局域网环境下开发数据库应用时:
(本文技术要点基于2025年8月的MySQL C API文档和实践经验总结)
本文由 城静竹 于2025-08-04发表在【云服务器提供商】,文中图片由(城静竹)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://up.7tqx.com/wenda/537492.html
发表评论