MySQL系列(二)C语言中MySQL的API使用
2.1 数据库建模
创建数据库
# 如果TEST_DB 存在,则先删除数据库,然后创建 TEST_DB;
DROP DATABASE TEST_DB;
// 创建表
CREATE DATABASE TEST_DB;
SHOW DATABASES;
// 使用表
USE TEST_DB;
创建表
USE TEST_DB;
# 创建 USER 表
CREATE TABLE TBL_USER(
U_ID INT PRIMARY KEY AUTO_INCREMENT,
U_NAME VARCHAR(32),
U_GENDER VARCHAR(8)
);
SHOW TABLES; # 显示所有的表
2.2 MySQL 插入数据API
在 MySQL
中插入数据语句如下,如何使用 C 在数据库中插入数据?
INSERT TBL_USER(U_NAME, U_GENDER) VALUES('test', 'male');
安装开发工具
sudo apt-get install libmysqlclient-dev
#include <mysql.h>
#include <stdio.h>
#include <string.h>
#define TEST_DB_SERVER_IP "202.118.18.124"
#define TEST_DB_SERVER_PORT 3306
#define TEST_DB_USER_NAME "admin"
#define TEST_DB_PASSWORD "admin123"
#define TEST_DB_DEFAULT_DB "TEST_DB"
#define SQL_INSERT_TBL_USER "INSERT TBL_USER(U_NAME, U_GENDER) VALUES('test', 'male');"
int main(){
// 创建数据库管道
MYSQL mysql;
// 初始化数据库,检查是否成功初始化
if (mysql_init(&mysql) == NULL){
printf("mysql_init : %s \n", mysql_error(&mysql));
return -1;
}
// 连接数据库,返回非0 成功
if(! mysql_real_connect(&mysql,
TEST_DB_SERVER_IP,
TEST_DB_USER_NAME,
TEST_DB_PASSWORD,
TEST_DB_DEFAULT_DB,
TEST_DB_SERVER_PORT,
NULL, //UNIX 对应 socket
0 // flag
))
{
printf("mysql real connect : %s \n" , mysql_error(&mysql));
return -2;
}
// 数据库查询,返回 0 成功
if (mysql_real_query(&mysql, SQL_INSERT_TBL_USER, strlen(SQL_INSERT_TBL_USER))){
printf("mysql real querry: %s \n" , mysql_error(&mysql));
return -3;
}
mysql_close(&mysql);
return 0;
}
编译运行文件,查看数据表
gcc -o insertTESTTBL insertTESTTBL.c -I /usr/include/mysql/ -l mysqlclient
查询数据库,数据已插入成功。
2.3 MySQL 查询数据API
node server
将MySQL
语句发送至数据库服务器db Server
中- 数据库服务器在执行该语句后,返回查询结果至
node server
的管道中 node server
从管道中取出查询结果,获取数据集合
#define SQL_SELECT_TBL_USER "SELECT * FROM TBL_USER;"
int test_mysql_select(MYSQL* handle){
// 1. `node server` 将 `MySQL` 语句发送至数据库服务器 `db Server` 中
// 数据库查询,返回 0 成功
if (mysql_real_query(handle, SQL_SELECT_TBL_USER , strlen(SQL_SELECT_TBL_USER))){
printf("mysql real querry: %s \n" , mysql_error(handle));
return -1;
}
// 2. 数据库服务器在执行该语句后,返回查询结果至 `node server` 的管道中
MYSQL_RES* res = mysql_store_result(handle);
if (res == NULL){
printf("mysql_store_result: %s \n" , mysql_error(handle));
return -2;
}
// 3. 获取数据集合,行列
int rows = mysql_num_rows(res);
printf("rows: %d\n", rows);
int fields= mysql_num_fields(res);
printf("fields: %d\n", fields);
// 4. 读取数据
MYSQL_ROW row ;
while ((row = mysql_fetch_row(res))){
int i = 0;
for (i = 0; i < fields; i++){
printf("%s\t", row[i]);
}
printf("\n");
}
mysql_free_result(res);
return 0;
}
编译运行,结果如下:
2.4 删除数据API
SET SQL_SAFE_UPDATES = 0;
DELETE FROM TEL_TEST WHERE U_NAME="test";
SET SQL_SAFE_UPDATES = 1;
使用存储过程删除:
DELIMITER $$
CREATE PROCEDURE PROC_DELETE_USER(IN UNAME VARCHAR(32))
BEGIN
SET SQL_SAFE_UPDATES = 0;
DELETE FROM TEL_TEST WHERE U_NAME=UNAME ;
SET SQL_SAFE_UPDATES = 1;
END
$$
DELIMITER ;
使用C语言在数据库中删除
#define SQL_DELETE_TBL_USER "DELETE FROM TEL_TEST WHERE U_NAME="test";"
if (mysql_real_query(&mysql, SQL_DELETE_TBL_USER , strlen(SQL_DELETE_TBL_USER ))){
printf("mysql real querry: %s \n" , mysql_error(&mysql));
return -1;
}
2.5 数据库中插入图片
- 读取图片,将图片发送至数据库服务器(
read
) - xx (
mysql_write_image
) - 从数据库中查询图片(
mysql_read_image
) - 保存图片,写入磁盘(
write
)
首先,读写图片实现如下
// filename : 读取路径 文件名
// buffer : 存储图片数据
int read_image(char* filename, char* buffer){
// 检查参数
if (filename == NULL || buffer == NULL){
return -1;
}
// 判断文件是否为空
FILE* fp = fopen(filename, 'rb');
if (fp == NULL){
return -2;
}
// 计算文件大小,文件末尾 - 文件头 = 偏移大小(文件大小)
fseek(fp, 0, SEEK_END);
int length = ftell(fp);
fseek(fp, 0, SEEK_SET);
// 每次读取 1 个字节,读取length次,存入 buffer
int size = fread(buffer, 1, length, fp);
if (size != length){
printf("fread failed : %d\n", size);
return -2;
}
fclose(fp);
return size;
}
int write_image(char* filename, char* buffer, int length){
if (filename == NULL || buffer == NULL || length <= 0){
return -1;
}
// 判断文件是否为空
FILE* fp = fopen(filename, 'wb');
if (fp == NULL){
return -2;
}
// buffer 中数据,以1个字节大小,写入fp中,写 length 次
fwrite(buffer, 1, length, fp);
if (size != length){
printf("fwrite failed : %d\n", size);
return -3;
}
fclose(fp);
return size;
}
// 定义插入图片的MySQL语句,? 表示占位符
#define SQL_INSERT_IMG_USER "INSERT TBL_USER (U_NAME, U_GENDER, U_IMGE) VALUES('test', 'man', ?);"
int mysql_write(MYSQL* handle, char* buffer, int length){
if (handle == NULL || buffer == NULL || length == 0){
return -1;
}
MYSQL_STMT* stmt = mysql_stmt_init(handle);
int ret = mysql_stmt_prepare(stmt, SQL_INSERT_IMG_USER, strlen(SQL_INSERT_IMG_USER));
if (ret){
printf("mysql stmt prepare: %s \n" , mysql_error(handle));
return -2;
}
MYSQL_BIND param = {0};
param.buffer_type = MYSQL_TYPE_LONG_BLOB;
param.buffer = NULL;
param.is_null = 0;
param.length = NULL:
// 绑定参数
ret = mysql_stmt_bind_param(stmt, ¶m);
if (ret){
printf("mysql stmt bind param: %s \n" , mysql_error(handle));
return -3;
}
// 将buffer 分段传送至数据服务器
ret = mysql_stmt_send_long_data();
if (ret){
printf("mysql stmt send long data: %s \n" , mysql_error(handle));
return -4;
}
}