Mysql c Api 开发笔记
第一个例子
用来测试mysql开发的环境是否搭建完成,测试的方式是调用一个Mysql的函数。
version.c文件
#include <stdio.h> #include <mysql.h> int main(int argc, const char *argv[]) { printf("Mysql client version:%s\n",mysql_get_client_info()); return 0; }
编译输出的结果:
gcc -I /usr/local/mysql/include/ -L /usr/local/mysql/lib/ -lmysqlclient version.c
输出结果:
Mysql client version:5.6.24
创建一个数据库
以下代码的作用是连接mysql数据库然后创建一个新的数据库用于接下来的测试
#include <mysql.h> #include <stdio.h> #include <stdlib.h> int main(int argc, const char *argv[]) { MYSQL *conn; conn=mysql_init(NULL); if(conn==NULL) { printf("错误:%u:%s\n",mysql_errno(conn),mysql_error(conn)); exit(1); } if(mysql_real_connect(conn,"192.168.10.212","admin","admin",NULL,0,NULL,0)==NULL) { printf("错误:%u:%s\n",mysql_errno(conn),mysql_error(conn)); exit(1); } if(mysql_query(conn,"create database testdb")){ printf("错误:%u:%s\n",mysql_errno(conn),mysql_error(conn)); } mysql_close(conn); return 0; }
我们通过命令方式来登录数据库发现testdb已经创建完成,说明程序已经正确执行。
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| agc |
| mysql |
| performance_schema |
| test |
| testdb |
+--------------------+
6 rows in set (0.00 sec)
我们将以上的功能分解成以下几个步骤:
1、初始化一个connection结构句柄
2、创建连接
3、调用query函数来执行sql语句
4、关闭连接
MYSQL *conn;
我们声明一个mysql的结构体指针,这个结构体是一个连接的句柄
conn=mysql_init(NULL);
这个mysql_init()函数获取一个连接的句柄
if(conn==NULL) { printf("错误:%u:%s\n",mysql_errno(conn),mysql_error(conn)); exit(1); }
我们检查返回值,如果mysql_init()函数调用失败,我们将错误信息和代码打印出来
if(mysql_real_connect(conn,"192.168.10.212","admin","admin",NULL,0,NULL,0)==NULL) { printf("错误:%u:%s\n",mysql_errno(conn),mysql_error(conn)); exit(1); }
mysql_real_connect()函数的作用是建立一个数据库连接,函数传递的形参的功能分别为:连接句柄,主机名,端口号,uxinsocket和结构客户端标识
if(mysql_query(conn,"create database testdb")){
printf("错误:%u:%s\n",mysql_errno(conn),mysql_error(conn));
}
有关mysql_query()的作用是执行一个SQL语句,上面的是执行一个数据库创建的sql语句
mysql_close(conn);
最后我们将之前创建的数据库连接关闭
创建和填充一张表
下面的代码的作用是创建一张表并且向这张表内插入一些数据
#include <stdio.h> #include <mysql.h> int main(int argc, char const* argv[]) { MYSQL *conn; conn=mysql_init(NULL); mysql_real_connect(conn,"192.168.10.212","admin","admin","testdb",0,NULL,0); mysql_query(conn,"create table writers(name varchar(25))"); mysql_query(conn, "INSERT INTO writers VALUES(‘Leo Tolstoy‘)"); mysql_query(conn, "INSERT INTO writers VALUES(‘Jack London‘)"); mysql_query(conn, "INSERT INTO writers VALUES(‘Honore de Balzac‘)"); mysql_query(conn, "INSERT INTO writers VALUES(‘Lion Feuchtwanger‘)"); mysql_query(conn, "INSERT INTO writers VALUES(‘Emile Zola‘)"); mysql_close(conn); return 0; }
我们不需要调用任何新的MySQL函数,只需要通过mysql_query()函数并可以进行表创建和插入数据的操作。
mysql_real_connect(conn,”192.168.10.212","admin","admin","testdb",0,NULL,0);
我们连接数据库并且指定一个默认的数据库名
mysql_query(conn,"create table writers(name varchar(25))”);
我们操作一张名为writers的表,这个表有一个varchar字段。
mysql_query(conn, "INSERT INTO writers VALUES(‘Leo Tolstoy’)");
向表writers插入一条数据,插入的内容是Leo Tolstoy
我们进入数据库查询表是否创建
mysql> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| writers |
+------------------+
1 row in set (0.00 sec)
查看数据插入是否成功
mysql> select * from writers;
+-------------------+
| name |
+-------------------+
| Leo Tolstoy |
| Jack London |
| Honore de Balzac |
| Lion Feuchtwanger |
| Emile Zola |
+-------------------+
5 rows in set (0.00 sec)
检索数据库数据
这个例子的作用是遍历一张表内的所有的数据并且将其输出出来。
步骤:
创建一个连接
执行查询
获取数据返回数据集
取出所有的行数据
释放返回数据集
#include <stdio.h> #include <mysql.h> int main(int argc, char **argv) { MYSQL *conn; MYSQL_RES *result; MYSQL_ROW row; int num_fields; int i; conn = mysql_init(NULL); mysql_real_connect(conn, "192.168.10.212", "admin", "admin", "testdb", 0, NULL, 0); mysql_query(conn, "SELECT * FROM writers"); result = mysql_store_result(conn); num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { for(i = 0; i < num_fields; i++) { printf("%s ", row[i] ? row[i] : "NULL"); } printf("\n"); } mysql_free_result(result); mysql_close(conn); }
appledeMacBook-Pro:数据库 apple$ ./a.out
Leo Tolstoy
Jack London
Honore de Balzac
Lion Feuchtwanger
Emile Zola
mysql_query(conn, "SELECT * FROM writers");
上面的代表是从writers表中输出所有名称
result = mysql_store_result(conn);
获取返回的字段总数
num_fields = mysql_num_fields(result);
获取行总数
while ((row = mysql_fetch_row(result)))
{
for(i = 0; i < num_fields; i++)
{
printf("%s ", row[i] ? row[i] : "NULL");
}
printf("\n");
}
每次取一行的数据并将其所有的数据输出到屏幕当中。
mysql_free_result(result);
释放资源
行标题
下面的例子的作用是查询数据的同时将表的标题打印出来
将进行这个操作之前我们需要创建一张新的表并且插入数据
mysql> create table friends (id int not null primary key auto_increment,
-> name varchar(20), age int);
Query OK, 0 rows affected (0.01 sec)
mysql> insert into friends(name, age) values(‘Tom‘, 25);
Query OK, 1 row affected (0.00 sec)
mysql> insert into friends(name, age) values(‘Elisabeth‘, 32);
Query OK, 1 row affected (0.07 sec)
mysql> insert into friends(name, age) values(‘Jane‘, 22);
Query OK, 1 row affected (0.00 sec)
mysql> insert into friends(name, age) values(‘Luke‘, 28);
Query OK, 1 row affected (0.00 sec)
#include <stdio.h> #include <mysql.h> int main(int argc, char **argv) { MYSQL *conn; MYSQL_RES *result; MYSQL_ROW row; MYSQL_FIELD *field; int num_fields; int i; conn = mysql_init(NULL); mysql_real_connect(conn, "192.168.10.212", "admin", "admin", "testdb", 0, NULL, 0); mysql_query(conn, "SELECT * FROM friends"); result = mysql_store_result(conn); num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { for(i = 0; i < num_fields; i++) { if (i == 0) { while((field=mysql_fetch_field(result))) { printf("%s ", field->name); } printf("\n"); } printf("%s ", row[i] ? row[i] : "NULL"); } } printf("\n"); mysql_free_result(result); mysql_close(conn); }
这个例子跟前面的一样只是添加了一个输出表标题的功能
while((field=mysql_fetch_field(result))) {
printf("%s ", field->name);
}
调用mysql_fetch_field()的作用是返回一个MYSQL_FIELD的结构体,我们可以通过这个结构体获取行标题名。
appledeMacBook-Pro:数据库 apple$ ./a.out
id name age
1 Tom 25
2 Elisabeth 32
3 Jane 22
4 Luke 28
插入图片到MySQL database
我们需要创建一张保存图片的表
create table images(id int not null primary key, data mediumblob); #include <stdio.h> #include <mysql.h> int main(int argc, char **argv) { MYSQL *conn; int len, size; char data[1000*1024]; char chunk[2*1000*1024+1]; char query[1024*5000]; FILE *fp; conn = mysql_init(NULL); mysql_real_connect(conn, "192.168.10.212", "admin", "admin", "testdb", 0, NULL, 0); fp = fopen("image.png", "rb"); size = fread(data, 1, 1024*1000, fp); mysql_real_escape_string(conn, chunk, data, size); char *stat = "INSERT INTO images(id, data) VALUES(‘1‘, ‘%s‘)"; len = snprintf(query, sizeof(stat)+sizeof(chunk) , stat, chunk); mysql_real_query(conn, query, len); fclose(fp); mysql_close(conn); }
上面的例子我们向数据库插入一张图片到images表中,这个图片可以最大为1M
fp = fopen("image.png", "rb");
size = fread(data, 1, 1024*1000, fp);
我们打开一张图片并且将其读入到一个数据数组当中
mysql_real_escape_string(conn, chunk, data, size);
我们将读入的二进制数据进行重新编码使其能够正确的插入到数据当中,避免插入特殊的字符而产生的错误。
char *stat = "INSERT INTO images(id, data) VALUES(‘1‘, ‘%s‘)";
len = snprintf(query, sizeof(stat)+sizeof(chunk) , stat, chunk);
这两行的作用是准备查询所需要的语句
mysql_real_query(conn, query, len);
执行查询
从数据库当中获取图片
在之前我们提供了一个例子是将图片插入到数据库当中,现在我们取出刚才所插入的图片
#include <stdio.h> #include <mysql.h> int main(int argc, char **argv) { MYSQL *conn; MYSQL_RES *result; MYSQL_ROW row; unsigned long *lengths; FILE *fp; conn = mysql_init(NULL); mysql_real_connect(conn, "192.168.10.212", "admin", "admin", "testdb", 0, NULL, 0); fp = fopen("image2.png", "wb"); mysql_query(conn, "SELECT data FROM images WHERE id=1"); result = mysql_store_result(conn); row = mysql_fetch_row(result); lengths = mysql_fetch_lengths(result); fwrite(row[0], lengths[0], 1, fp); mysql_free_result(result); fclose(fp); mysql_close(conn); }
这个例子是从数据库取出我们刚才所插入的图片并且保存成一张图片文件
p = fopen("image2.png", "wb");
打开一个文件用于写入
mysql_query(conn, "SELECT data FROM images WHERE id=1");
查询id=1的图片
row = mysql_fetch_row(result):
取出行数据
lengths = mysql_fetch_lengths(result);
获取图片的存储容量
fwrite(row[0], lengths[0], 1, fp);
调用fwrite来写入图片