mysql学习笔记1【利用mysql connector/c 访问数据库】

2018-06-08


最近想学习一下mysql,看了一下书《MySQL必知必会》, 感觉书讲的还不错,也不是很厚,260页,大略的翻完了,然后自己也下载了mysql安装了,实际操作了一下,感觉书里面前2章内容略微陈旧了,

简单的管理数据库,查询可以直接安装mysql workbench,感觉界面挺不错,也很好用。那个 mysql shell似乎可以甩在一边不用了。
对着书大概了用了一些mysql 语句,对mysql有点认识后,打算用c语言来访问mysql服务器,进行一些操作。找了一下,看见有一些库給不同的语言用,来和mysql交互。比如c语言可以用 mysql connector/c 库。

现在记录一下我在windows系统下,利用visual stdudio 2015 ,用c语言 访问mysql数据库,进行了一个简单查询语句的整个过程。


工程代码如下:

 1 #include <stdio.h>
 2 
 3 #include <mysql.h>
 4 
 5 #pragma comment(lib, "ws2_32.lib")
 6 #pragma comment(lib, "Secur32.lib")
 7 #pragma comment(lib, "mysqlclient.lib")
 8 //#pragma comment(lib, "libmysql.lib")  使用这个总是会报错, lnk1107 文件无效或损坏,无法在0x348处读取
 9 
10 #define LOG(...)  fprintf(stderr, __VA_ARGS__)
11 
12 int main(int argc, char* argv[])
13 {
14     MYSQL* pmysql = mysql_init(NULL);
15     if (pmysql == NULL)
16     {
17         LOG("初始化mysql库失败\n");
18         return -1;
19     }
20 
21     MYSQL* ret = mysql_real_connect(pmysql, "localhost","test","test*","world",0,NULL,0);
22     if (ret == NULL)
23     {
24         LOG("连接到数据库 %s:%s 失败\n","localhost","world");
25         return -1;
26     }
27 
28     int ret_query = mysql_query(pmysql,"SELECT * FROM world.city;");
29     if (ret_query == 0)
30     {
31         MYSQL_RES * my_result = mysql_store_result(pmysql);
32 
33         int num = mysql_num_fields(my_result);
34         int i;
35         MYSQL_ROW row;
36         while ((row = mysql_fetch_row(my_result)) != NULL)
37         {
38             for (i = 0; i < num; i++)
39             {
40                 printf("%s\t", row[i]);
41             }
42             printf("\n");
43         }
44 
45         // 释放获取的结果
46         mysql_free_result(my_result);
47     }
48 
49     mysql_close(pmysql);
50     mysql_library_end();
51     return 0;
52 }

 

完整的工程可以到我的github上下载      

https://github.com/fish404/mysql_learning 

 

 

编译时候有几个地方要注意:

1、需要指定mysql.h 所在的头文件的路径,vs 在项目属性中设置。项目属性页 --》 c/c++ --》常规 --》附加包含目录中指定,最好用双引号将路径包含起来,如我的路径是 "C:\Program Files (x86)\MySQL\MySQL Connector C 6.1\include"。

2、需要指定 mysqlclient.lib 所在的库路径,注意这个路径跟你的vs 的版本有关,比如我的是 vs 2015,连接的库版本也要是2015编译出来的,对应的connector lib目录下 vs14目录,路径是 “C:\Program Files (x86)\MySQL\MySQL Connector C 6.1\lib\vs14”。

3、不要直接在属性也中指定依赖的库,否则连接的时候总是报错,搜了一下不知道是什么原因,最后用代码文件开头 #pragma comment(lib, "mysqlclient.lib") 编译通过。

4、还需要依赖 另外两个库 ws2_32.lib 和 Secur32.lib,跟上一点一样指定。

5、vs 配置管理器中选择x86,则也要安装 mysql  connector/c 的x86版本,前面1,2包含的路径也要是x86版本的路径。x64版本的不知道为何,总是报错。

6、连接静态库 mysqlclient.lib 可以运行,但是用动态库libmysql.dll 总是失败。暂时没有深究原因。




参考文档:
1、https://dev.mysql.com/doc/refman/5.6/en/c-api-function-overview.html    概述说明
2、https://dev.mysql.com/doc/refman/5.6/en/c-api-functions.html     各个函数详细参数说明,返回值意义等
3、https://www.codeproject.com/Articles/34646/Accessing-MySQL-data-base-using-MySQL-C-API, 别人写的一个示例,用c++包装了。


下面一段是对参考文档1 的翻译,大概是讲了使用的步骤,一些注意事项。

 

连接的库
libmysqlclient 或者 libmysqld
 
mysql_library_init() 初始化mysql客户库 。这个函数不是线程安全,多线程情况下一定要先调用这个函数之后,再生成线程,调用其它库函数。
 
mysql_init() 初始化一个连接处理器。 会间接调用mysql_library_init函数,非多线程环境下,可以省略上面这个函数。
 
mysql_real_connect() 连接到服务器
 
函数原型是 MYSQL *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 client_flag)
 
mysql_close() 关闭到服务器的连接
 
mysql_library_end() 用完了mysql库后需要释放,不然有些内存会保持分配,让一些工具软件抱怨。
 
 
连接成功后,可以调用下面两个函数来执行sql语句。
 
mysql_query() 期望查询语句是null结尾。 每一次调用这个查询后,接着调用mysql_store_result 或者 mysql_use_result来处理结果。
 
mysql_real_query() 如果字符串中有二进制的数据,必须使用这个函数。
 
sql语句有select语句,非select语句(如insert,update,delete)。对非select语句,
可以调用 mysql_affected_rows() 得到有多少行收到影响。
 
对select语句(包括select,show,describe,explain),你将获取到选中的行作为结果集合。
 
有2种方式处理结果集合。
  • 一个是mysql_store_result(),这个函数一次性获取所有的选中的行,保存到客户处。这种方式用的比较多,因为你可以顺序访问所有的行,并且可以前后移动行,通过mysql_row_seek() 或者 mysql_data_seek() 来改变结果集合中的当前行位置。
还可以通过mysql_num_rows()知道一共有多少行返回了。
这个方式缺点是可能如果返回结果太多,内存可能不够,而且等待时间可能较大。
  • 另一个是 mysql_use_result(),这个函数只是初始化获取,但是实际上还没有从服务器获取任意一行数据。
 
上面任意一种方式,都可以调用mysql_fetch_row() 来访问获取的结果的一行。对第二种方式,该函数实际是从服务器获取数据。
 
mysql_fetch_field() 可以用来获取各个字段信息,通过在一行中连续调用。也可以通过mysql_fetch_field_direct() 指定字段号来获取字段信息。mysql_field_seek() 可以改变当前字段游标位置。
 
mysql_fetch_fields() 可以一次获取所有的字段信息。
 
mysql_fetch_lengths() 可以获取每行的长度信息。
mysql_free_result() 用完结果后释放内存。
关于mysql_store_result() 还有一点补充,如果这个函数返回成功,那么sql语句是select语句。如果失败,进一步调用 mysql_field_count() 来判断结果是否符合预期,如果这个函数返回0,说明sql语句不需要返回语句,以为着这是一个insert,update,
delete语句。如果不为0,则说明它期待返回数据,sql语句是select语句,并且失败了。
 

 

转载于:https://www.cnblogs.com/xiaoyuer403/p/9156781.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值