Mysql数据库动态库: libmysql.dll libmysql.lib mysql.h WinSock2.h
Mysql API数据结构 (mysql.h)
MYSQL:连接数据库前,必须先创建MYSQL变量,此变量在很多Mysql API函数会用到。它包含了一些连接信息等数据。
MYSQL_RES:MYSQL_RES结构体中包含了查询结果集,也就是从数据库中查询到的数据。可以使用mysql_store_result或mysql_use_result函数获得。
MYSQL_ROW:MYSQL ROW的定义如下:typedef char **MYSQL_ROW;可见,它实际上是char **类型,指向一个字符串数组。存储一行中各段字符数组,可以通过mysql_fetch_row函数获得。
MYSQL_FIELD:MYSQL_FIELD中包含了字段名、字段类型和大小等信息。可以重复调用mysql_fetch_field函数获得所有字段的信息。
Mysql C API编程步骤
1、首先我们要包含mysql的头文件,并链接mysql动态库。
#include <WinSock2.h> // 进行网络编程需要winsock2.h
#include <mysql.h>
#pragma comment(lib, "libmysql.lib")
2、创建MYSQL变量。如:
MYSQL mysql;
3、初始化MYSQL变量。
mysql_init(&mysql);
4、调用mysql_real_connect函数连接Mysql数据库。
mysql_real_connect函数的MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,const char *user,const char *passwd,const char *db,unsigned int port,const char *unix_socket,unsigned long clientflag);
参数说明:mysql--前面定义的MYSQL变量;host--MYSQL服务器的地址;user--登录用户名;passwd--登录密码;db--要连接的数据库;port--MYSQL服务器的TCP服务端口;unix_socket--unix连接方式,为NULL时表示不使用socket或管道机制;clientflag--Mysql运行为ODBC数据库的标记,一般取0。
连接失败时该函数返回0。
5、调用mysql_real_query函数进行数据库查询。mysql_real_query函数的原型如下:
int STDCALL mysql_real_query(MYSQL *mysql, const char *q, unsigned long length);
参数说明:mysql--前面定义的MYSQL变量;q--SQL查询语句;length--查询语句的长度。
查询成功则该函数返回0。
6、通过调用mysql_store_result或mysql_use_result函数返回的MYSQL_RES变量获取查询结果数据。
两个函数的原型分别为:
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql);
这两个函数分别代表了获取查询结果的两种方式。第一种,调用mysql_store_result函数将从Mysql服务器查询的所有数据都存储到客户端,然后读取;第二种,调用mysql_use_result初始化检索,以便于后面一行一行的读取结果集,而它本身并没有从服务器读取任何数据,这种方式较之第一种速度更快且所需内存更少,但它会绑定服务器,阻止其他线程更新任何表,而且必须重复执行mysql_fetch_row读取数据,直至返回NULL,否则未读取的行会在下一次查询时作为结果的一部分返回,故经常我们使用mysql_store_result。
7、调用mysql_fetch_row函数读取结果集数据。
上述两种方式最后都是重复调用mysql_fetch_row函数读取数据。mysql_fetch_row函数的原型如下:
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
参数result就是mysql_store_result或mysql_use_result的返回值。
该函数返回MYSQL_ROW型的变量,即字符串数组,假设为row,则row[i]为第i个字段的值。当到结果集尾部时,此函数返回NULL。
8、结果集用完后,调用mysql_free_result函数释放结果集,以防内存泄露。mysql_free_result函数的原型如下:
void STDCALL mysql_free_result(MYSQL_RES *result);
9、不再查询Mysql数据库时,调用mysql_close函数关闭数据库连接。mysql_close函数的原型为:
void STDCALL mysql_close(MYSQL *sock);
例子:
1. int main() {
2. MYSQL mysql;
3. MYSQL_RES *res;
4. MYSQL_ROW row;
5. mysql_init(&mysql); // 初始化MYSQL变量
6. // 连接Mysql服务器,本例使用本机作为服务器。访问的数据库名称为"msyql",参数中的user为你的登录用户名,***为登录密码,需要根据你的实际用户进行设置
7. if (!mysql_real_connect(&mysql, "127.0.0.1", "user", "123", "mysql", 3306, 0, 0)) {
8. cout << "mysql_real_connect failure!" << endl;
9. return 0;
10. }
11. if (mysql_real_query(&mysql, "select * from user", (unsigned long)strlen("select * from user"))){ // 查询mysql数据库中的user表
12. cout << "mysql_real_query failure!" << endl;
13. return 0;
14. } // 存储结果集
15. res = mysql_store_result(&mysql);
16. if (NULL == res) {
17. cout << "mysql_store_result failure!" << endl;
18. return 0;
19. }
20. // 重复读取行,并输出第一个字段的值,直到row为NULL
21. while (row = mysql_fetch_row(res)) {
22. cout << row[0] << endl;
23. }
24. mysql_free_result(res); // 释放结果集
25. mysql_close(&mysql); // 关闭Mysql连接
26. return 0; }
10.Char * mysql_get_client_info() 显示mysql客户端版本
MySQL client version: 5.0.38
11.int mysql_num_fields(MYSQL_RES *result) 返回结果子表中域(字段)的个数
12. MYSQL_FIELD * mysql_fetch_field(MYSQL_RES *result) 返回结果子表中的域结构体指针
13.Void mysql_real_escape_string(MYSQL* con, char* savedata, char *data, int size) 在将二进制数据(非文本)保存到数据库之前,需要转义,否则数据库不能正常保存,取出数据时,无需解转移。转义时一个字符转义后2个字符,所以savedata内存必须为data的2倍
14. unsigned long * mysql_fetch_lengths(MYSQL_RES *result) 获取结果中各个字符串的长度,返回为1维数组
一些有用的例子:
#include
#include
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, "localhost", "zetcode", "passwd", "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);
}
The example prints all names from the writers table.
$ ./select
Leo Tolstoy
Jack London
Honore de Balzac
Lion Feuchtwanger
Emile Zola
mysql_query(conn, "SELECT * FROM writers");
We execute the query, that will retrieve all names from the writers database.
result = mysql_store_result(conn);
We get the result set.
num_fields = mysql_num_fields(result);
We get the number of fields in the table.
while ((row = mysql_fetch_row(result)))
{
for(i = 0; i < num_fields; i++)
{
printf("%s ", row[i] ? row[i] : "NULL");
}
printf("\n");
}
We fetch the rows and print them to the screen.
mysql_free_result(result);
We free the resources.
Column headers
In the next example, we will retrieve data and show the their column names from the table.
For this, we will create a new table friends.
mysql> create table friends (id int not null primary key auto_increment,
name varchar(20), age int);
mysql> insert into friends(name, age) values(‘Tom‘, 25);
mysql> insert into friends(name, age) values(‘Elisabeth‘, 32);
mysql> insert into friends(name, age) values(‘Jane‘, 22);
mysql> insert into friends(name, age) values(‘Luke‘, 28);
We insert some data into the table.
#include
#include
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, "localhost", "zetcode", "passwd", "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);
}
The example is similar to the previous one. It just adds column header names to it.
while(field = mysql_fetch_field(result)) {
printf("%s ", field->name);
}
The mysql_fetch_field() call returns a MYSQL_FIELD structure. We get the column header names from this structure.
$ ./headers
id name age
1 Tom 25
2 Elisabeth 32
3 Jane 22
4 Luke 28
And this is the output of our program.
Inserting images into MySQL database
Some people prefer to put their images into the database, some prefer to keep them on the file system for their applications. Technical difficulties arise when we work with millions of images. Images are binary data. MySQL database has a special data type to store binary data called BLOB (Binary Large Object).
mysql> describe images;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | | |
| data | mediumblob | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
This is the table, that we will use in our example. It can be created by the following SQL statement.
create table images(id int not null primary key, data mediumblob);
#include
#include
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, "localhost", "zetcode", "passwd", "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);
}
In this example, we will insert one image into the images table. The image can be max 1 MB.
fp = fopen("image.png", "rb");
size = fread(data, 1, 1024*1000, fp);
Here we open the image and read it into the data array.
mysql_real_escape_string(conn, chunk, data, size);
Binary data can obtain special characters, that might cause troubles in the statements. We must escape them. The mysql_real_escape_string() puts the encoded data into the chunk array. In theory, every character might be a special character. That‘s why the chunk array two times as big as the data array. The function also adds a terminating null character.
char *stat = "INSERT INTO images(id, data) VALUES(‘1‘, ‘%s‘)";
len = snprintf(query, sizeof(stat)+sizeof(chunk) , stat, chunk);
These two code lines prepare the MySQL query.
mysql_real_query(conn, query, len);
Finally, we execute the query.
Selecting images from MySQL database
In the previous example, we have inserted an image into the database. In the following example, we will select the inserted image back from the database.
#include
#include
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, "localhost", "zetcode", "passwd", "testdb", 0, NULL, 0);
fp = fopen("image.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);
}
In this example, we will create an image file from the database.
fp = fopen("image.png", "wb");
We open a file for writing.
mysql_query(conn, "SELECT data FROM images WHERE id=1");
We select an image with id 1.
row = mysql_fetch_row(result);
The row contains raw data.
lengths = mysql_fetch_lengths(result);
We get the length of the image.
fwrite(row[0], lengths[0], 1, fp);
We create the image file using the fwrite() standard function call.