赞
踩
翻译自:https://dev.mysql.com/doc/refman/5.7/en/c-api-function-overview.html
应用程序使用MySQL有如下几个步骤:
调用 mysql_library_init()和mysql_library_end()的目的是对MySQL合适的初始化与终止化。对于涉及客户端库的应用,他们提供改进的内存管理。如果你不调用mysql_library_end(),那么之前申请的一块内存将会一直存在(这个并不会增加应用程序内存的使用量,但是有些内存泄露检测器会检测到)。对于服务器端的程序,这两个函数可以开始和结束服务器端数据库。
在一个非多线程的环境中,调用mysql_library_init()可能可以省略,因为 mysql_init()将在必要的时候自动调用它。然而mysql_library_init()在多线程环境中并不是安全的,mysql_init()自动调用mysql_library_init()时也同样不安全。因此,要么你在增加任何线程之前调用mysql_library_init(),要么使用mutex来保护这个调用(不管是直接调用mysql_library_init()还是间接通过调用mysql_init()调用)。这个步骤必须在任何其他客户端库调用之前完成。
为了连接服务器端数据库,调用mysql_init()来初始化一个连接句柄,然后调用 mysql_real_connect()(需要有其他信息,比如host名字,用户名,密码等)。 mysql_real_connect()会将重连接标志位(reconnect flag )(MYSQL结构体中一部分)置为1(API版本5.0.3之前)或者置为0(API版本5.0.3之后)。这个标志位为1时,表明如果失去连接导致数据库查询或者操作语句不能执行,将在放弃前尝试重新连接。你可以使用 mysql_options()中的MYSQL_OPT_RECONNECT选项来控制重连接行为。最后,当数据库操作全部完成后,调用mysql_close()来关闭它。
当连接数据库成功后,客户端可以使用 mysql_query()或者mysql_real_query()发送SQL操作语句给服务器。这两个函数的区别是mysql_query()期望查询是一个 null-terminated string(以’\0’结尾的字符串),而mysql_real_query()则期望是一个counted string。如果字符串包含二进制数据(其中可能包含NULL字节),那么你必须使用mysql_real_query()。
对于每个非选择( non-SELECT )的查询(比如,INSERT,UPDATE,DELETE),你可以通过调用mysql_affected_rows()来发现多少行被改变。
对于SELECT查询,你可以以result集合检索被选择的行(注意,一些类似于SELECT的语句,包括SHOW,DESCRIBE和EXPLAIN,其实跟SELECT语句一样的)。
对于客户端来说,有两个方式来处理result集合。其中一个方式是通过调用 mysql_store_result()来一次性获得整个查询结果。整个函数从服务器数据库中获得所有的行,并保存在客户端中。第二个方式是通过调用mysql_use_result()来初始化一行一行的读取检索结果。这个函数只进行初始化,实际上并不会从服务器中获取任何的一行。
在上面两个情况下,你可以通过调用 mysql_fetch_row()来获取每一行。使用mysql_store_result()时,mysql_fetch_row()函数获取每一行,其中数据之前就已经从服务器数据库中获得;使用mysql_use_result()时,mysql_fetch_row()函数实际上是从服务器数据库中实时获取每一行。可以调用mysql_fetch_lengths()来获取每一行数据的大小信息。
当你操作完result集合后,调用 mysql_free_result()来释放之前使用的内存。
上面两个检索机制是互补的。可以根据客户端程序的具体应用来选择使用哪种方法。实际上,客户端更常使用mysql_store_result()。
mysql_store_result()的其中一个优点是,因为所有的行已经从数据库中获取,因此你不仅可以顺序的获取每一行,还可以使用 mysql_data_seek()或者mysql_row_seek()来改变当前在result集合中读取的位置(行号)。你也可以通过调用 mysql_num_rows()来获知有多少行。另一方面,mysql_store_result()对内存的要求可能会很高(对于很大的result集合来说),因此,你会更大概率上遇到内存不够用的情况。
mysql_use_result()的一个优点是客户端只需要很少的内存空间来存放result集合,因为每次只需要存一行的数据(因为申请的内存空间少了,mysql_use_result()运行速度也更快了)。缺点是你必须快速处理每一行来避免过多占用服务器数据库,而且你也不能在result集合中随机访问每一行,你只能顺序的访问每一行。全部的总行数你是不知道的,直到全部检索完毕。还有,你必须全部检索完所有行,即使当你在中间部分已经找到了想要的结果。
API函数在不需要知道是否是一个SELECT语句的情况下,提供了客户端对操作语句的一个合适的响应。你可以在调用每个mysql_query() (或者 mysql_real_query())函数之后,再调用 mysql_store_result()。如果result集合调用成功,这个操作语句是一个SELECT语句,然后就可以读取每一行。如果返回结果为失败,那么调用 mysql_field_count() 来查看失败结果是否是实际所期待的(你想得到的结果就是失败)。如果mysql_field_count()返回0,操作语句不返回任何数据(说明操作语句是一个INSERT,UPDATE或者DELETE语句等等),因此也不会返回行数据。如果mysql_field_count()返回非零值,那么操作语句本应该返回数据,实际却没有返回。这个表明是一个SELECT操作语句,但是操作失败了。可以去mysql_field_count()查看如何处理这种情况。
mysql_store_result() 和 mysql_use_result() 都可以让你获取有关result集合的字段信息(字段的序号,名称和类型等)。你可以通过重复调用 mysql_fetch_field()来顺序的获取信息,或者调用 mysql_fetch_field_direct()(该函数需要给定序号)来获取某一序号的信息(不需要按顺序获取)。可以通过调用mysql_field_seek()来改变当前字段光标位置。也可以通过调用mysql_fetch_fields()一次性获取全部字段。
对于检测和报告错误,MySQL提供了获取用户信息的渠道,即使用 mysql_errno() 和 mysql_error() 两个函数。这两个函数为最新调用的函数提供了返回错误代号或者错误信息,可以让你知道错误什么时候发生和错误是什么。
举例:
服务器上数据库表单如下:
示例代码如下:
- #include<iostream>
- #include<string>
- #include<mysql.h>
- #include <iomanip>
-
- using namespace std;
-
- int main()
- {
- //必备数据结构
- MYSQL mydata; //=mysql_init((MYSQL*)0);
- if (NULL != mysql_init(&mydata))
- cout << "mysql_init()succeed" << endl;
- else {
- cout << "mysql_init()failed" << endl;
- return -1;
- }
-
- //初始化数据库
- if (0 == mysql_library_init(0, NULL, NULL))
- cout << "mysql_library_init()succeed" << endl;
- else {
- cout << "mysql_library_init()failed" << endl;
- return -1;
- }
- //连接数据库 //这里的地址,用户名,密码,数据库,端口可以根据自己本地的情况更改
- if (NULL != mysql_real_connect(&mydata, "192.168.110.218", "root", "123456", "test", 3306, NULL, 0))
- {
- cout << "mysql_real_connect()succeed" << endl;
- }
- else
- {
- cout << "mysql_real_connect()failed" << endl;
- return -1;
- }
-
- //MYSQL myCont;
- MYSQL_RES *result;
- MYSQL_ROW sql_row;
- int res;
- //mysql_query(&mydata, "SET NAMES GBK"); //设置编码格式
- res = mysql_query(&mydata, "select * from fruits");//查询
- if (!res)
- {
- result = mysql_store_result(&mydata);
- // result = mysql_use_result(&mydata);//使用这句的时候,必须使用mysql_fetch_row读完全部的行,直到为NULL
- if (result)
- {
- unsigned int num_fields = mysql_num_fields(result);
- cout << "num_fields: " << num_fields << endl;
-
- MYSQL_FIELD *field;
- // mysql_field_seek(result, 1);
- while ((field = mysql_fetch_field(result)))
- {
- cout << setiosflags(ios::left)<< setw(15) << field->name;
- }
- cout << endl;
- //mysql_data_seek(result, 2);
- while (sql_row = mysql_fetch_row(result))//获取具体的数据
- {
- for (int i = 0; i < mysql_num_fields(result); i++)
- {
- if (sql_row[i])
- cout << setiosflags(ios::left)<< setw(15) << sql_row[i];
- // else cout << " ";
- }
- cout << endl;
- }
- }
- mysql_free_result(result);
- }
- else
- {
- cout << "query sql failed!" << endl;
- }
-
- //操作……
- mysql_close(&mydata);
- mysql_library_end();
- cout << "end..." << endl;
- getchar();
- return 0;
- }
程序运行结果如下:
(1660条消息) mysql的C API函数简介_mysql_library_init_hjl240的博客-CSDN博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。