连接/断开MySQL数据库服务器
好,我们接着上一篇继续编写第一个 MySQL 数据库应用程序。接下来,我们要写代码连接到 MySQL 的数据库服务器。需要说明一下,我们通过一本书,叫《MySQL, 4th Edition》,来学习 MySQL 数据库编程,所以样例代码都摘录自这本书。并且为了方便编译和测试书里的代码,我们都是按照书里前边 MySQL 数据库的操作,预先创建了用户和样例数据库:
用户名:sampadm
密码:secret
数据库名称:sampdb
有了这些前提条件,我们就可以开始学习书中的代码了。以下就是测试数据库服务器的连接和断开代码:
// exec_stmt.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <my_global.h> // 这个头文件必须是第一个被包含的文件 #include <my_sys.h>#include <mysql.h>#include <my_getopt.h>#include <m_string.h> // 需要的函数strdup()在这个头文件中声明static char *opt_host_name = NULL; // 服务器主机 (默认=localhost)static char *opt_user_name = "sampadm"; // 用户名 (默认=登陆名)static char *opt_passWord = "secret"; // 密码 (默认=无)static unsigned int opt_port_num = 0; // 端口号(使用内置值)static char *opt_socket_name = NULL; // 套接字名称 (使用内置值)static char *opt_db_name = "sampdb"; // 数据库名称(默认=无)static unsigned int opt_flags = 0; // 连接标志connection flags (无)static int ask_password = 0; // 是否请求密码static MYSQL *conn; // 连接数据库句柄的指针int _tmain(int argc, _TCHAR* argv[]){ // 将一个全局变量指向程序的名称并调用my_init()。 // 这个全局变量会被MySQL库用于错误信息中。// MY_INIT (argv[0]); // 执行一些设置操作 my_init(); // 初始化客户端库 if (mysql_library_init(0, NULL, NULL)) { fPRintf(stderr, "mysql_library_init() falied/n"); exit(1); } // 初始化连接句柄 conn = mysql_init(NULL); if (conn == NULL) { fprintf(stderr, "mysql_init() failed (probably out of memory)/n"); exit(1); } // 连接到服务器 if (mysql_real_connect(conn, opt_host_name, opt_user_name, opt_password, opt_db_name, opt_port_num, opt_socket_name, opt_flags) == NULL) { fprintf(stderr, "mysql_real_connect() failed/n"); mysql_close(conn); exit(1); } // ... 在这里发出查询语句并处理返回的结果 ... // 断开与服务器的连接 mysql_close(conn); // 停止客户端库 mysql_library_end(); return 0;}以上代码中的注释已经基本把程序的流程说清楚了。这里边还有几点需要说明一下。
1. 我们把用户名、密码和数据库名称写在程序代码开头的全局变量声明中。这种硬编码显然是不对的。未来要修改代码,让用户自己从外部给程序提供这些信息。因为目前仅是测试服务器的连接与断开,所以先这样。
2. 这本书里用到的代码都是在linux上用GCC编译器编译的。虽然作者说 Windows 用户一样能编译,但是貌似并不完全如此。毕竟大家的开发环境千差万别。比如,请注意在 _tmain() 函数的开头,书上原来的代码说要调用一个叫做 MY_INIT 的宏,并且把程序的名称作为参数传给这个宏。说是这个宏会做一些初始化操作,并且纪录程序的名称,未来可以用这个名称给用户显示一些错误信息(如果有错误发生的话)。但是VS.NET 2003无法编译这个函数,总是报错。于是我们在 my_sys.h 这个文件中,在第40行,找到了关于这个宏的定义:
我们发现这个宏实际是将传递给参数 name 的值保存在一个叫 my_progname 的全局变量中,然后调用函数 my_init()。幸运的是,如果我们不调用这个宏,而是直接调用 my_init() 这个函数,编译可以通过。于是我们就修改了代码,直接调用 my_init() 。未来还有一个函数调用无法通过编译,这个函数是 get_tty_password() 。这个函数是用来在命令行提示符下向用户索要密码的。但是这个函数并不在我们的 VS 编译器自带的函数库里,所以编译器会提醒找不到这个函数。在网上能找到这段函数的定义,比如在这里。但是好像会把问题搞复杂,增加编译咱们第一个 MySQL 程序的难度。所以我们选择不调用这个函数。只能留在以后,对 C/C++ 越来越熟悉后,再回来研究这个函数吧。
现在,如果你在 VS 里选择菜单“生成-〉生成 exec_stmt”,程序就会编译通过(至少在我们的机器上是这样的)。
好,我们来运行这个程序试验一下。在 Windows xp 上依次选择“开始-〉所有程序-〉附件-〉命令提示符”,然后定位到编译的可执行程序所在的目录,运行程序:
如果运气好的话,不会有错误报告,什么事情也不会发生,因为我们的代码除了连接/断开数据库服务器外,啥也没干。
先到这里。
顺便说一下,在这里只是摘录了书中必要的代码。要想完整、系统地学习 MySQL 编程,还是要自己买书,重头到尾好好学习。
新闻热点
疑难解答