(1)初始化MySQL库
(2)初始化数据库链接句柄
(3)链接数据库
(4)经过SQL语句操做数据库并处理相应数据
(5)关闭数据库链接
(6)结束MySQL库
经过这五个步骤便可实现数据库的访问,具体代码和分析以下: mysql
//1.定义访问数据库所需变量 MYSQL * myData; MYSQL_RES * res; MYSQL_ROW row; //2. 初始化MySQL库和数据库链接句柄 myData = mysql_init((MYSQL*) 0); //3. 设置选项 mysql_options(myData, MYSQL_SET_CHARSET_NAME , “utf8”); char cOpt = 1; mysql_options(myData, MYSQL_OPT_RECONNECT, cOpt); //4. 链接数据库,MYSQL_IP和MYSQL_PORT表示数据库的IP和端口 // MYSQL_ACCOUNT, MYSQL_PASSWORD表示数据库链接的账号和密码,MYSQL_DBNAME表示所要访问的数据库名 mysql_real_connect( myData, MYSQL_IP, MYSQL_ACCOUNT, MYSQL_PASSWORD, MYSQL_DBNAME, MYSQL_PORT,NULL, 0 ) //5. 经过SQL语句操做数据库并处理相应数据 //5.1 新建用户名为abcdef,密码为123456的记录 mysql_query(myData, "insert into TestTable value(‘abcdef’,’ 123456’)"); //5.2 显示全部记录 mysql_query(myData, "select * from TestTable"); //5.3 将查询结果保存到res中 res = mysql_store_result( myData ) ; //5.4 逐条显示记录 int j = 0; while ( row = mysql_fetch_row( res ) ) {//获取一条记录 j = mysql_num_fields( res ) ;//获取每条记录的字段数 for ( k = 0 ; k < j ; k++ ) { printf( “%s”, row[k] ) ; printf( “\n”) ; } } //5.5 释放res mysql_free_result( res ) ; //6. 检查数据库链接是否有效,当且仅当设置了MYSQL_OPT_RECONNECT选项有效 unsigned long qwPreId = mysql_thread_id( myData );//重连以前的id mysql_ping( myData ); unsigned long qwNextId = mysql_thread_id( myData );//重连以后的id //7. 关闭数据库链接 mysql_close( myData ); //8. 结束MySQL库 mysql_library_end();
关于代码的几点说明:
(1)定义变量中的三个数据结构为访问MySQL所需,MYSQL结构表示一个数据库链接的句柄,其中包含了数据库链接所需的参数,MYSQL_RES结构表示数据库访问中一个查询的返回结果,MYSQL_ROW结构表示返回结构中的一条记录;
(2)获取查询结果res并处理完毕,必须释放res,不然会形成内存泄露 。
(3)在单线程时,步骤初始化MySQL库和数据库链接句柄可合并, 由mysql_init()来处理。该函数会自动调用函数mysql_library_init()来初始化MySQL库,同时初始化链接句柄。
(4)mysql_connect()是已经废弃的方法,它参数的含义和mysql_real_connect()是一致的,惟一不一样的是MYSQL指针可能为空,在这种状况下,API会自动管理这部份内存,这将会致使当链接失败时,没法获取错误信息,由于获取错误信息须要有效的MYSQL指针 。
(5)mysql_query()与mysql_real_query() 的区别是mysql_query不能包含任何的二进制数据(例如BLOB字段),由于二进制信息中的\0会被误判为语句结束。
(6)若是频繁地调用 mysql_init 和 mysql_close 的话,记得在 mysql_close 以后调用 mysql_library_end() 来释放未被释放的内存,不然会出现内存泄漏sql
多线程环境下的数据库访问须要保证线程安全。Windows版本的MySQL C API函数都是线程安全的,除了mysql_library_init(),而咱们刚才的代码中使用的mysql_init()函数会自动调用函数 mysql_library_init()来初始化MySQL库,而在多线程环境下,须要不一样的初始化代码和清理代码。具体过程以下:
(1)在主函数中调用mysql_library_init( )来初始化MySQL库;
(2)启动各数据库访问线程
(3)主函数等待各个线程的结束
(4)调用mysql_library_end( )清理MySQL库。
其中数据库访问线程的代码和单线程数据库访问代码相似,可是须要发生一些变化: 数据库
//1.定义访问数据库所需变量 MYSQL * myData; MYSQL_RES * res; MYSQL_ROW row; //2. 初始化MySQL库和数据库链接句柄 mysql_init(); mysql_thread_init(); //3. 初始化myData myData = malloc(sizeof(MYSQL)); memset(&myData, 0, sizeof(MYSQL)) //4. 设置选项 mysql_options(myData, MYSQL_SET_CHARSET_NAME , “utf8”); char cOpt = 1; mysql_options(myData, MYSQL_OPT_RECONNECT, cOpt); //5. 链接数据库,MYSQL_IP和MYSQL_PORT表示数据库的IP和端口 // MYSQL_ACCOUNT, MYSQL_PASSWORD表示数据库链接的账号和密码,MYSQL_DBNAME表示所要访问的数据库名 mysql_real_connect( myData, MYSQL_IP, MYSQL_ACCOUNT, MYSQL_PASSWORD, MYSQL_DBNAME, MYSQL_PORT,NULL, 0 ) //6. 经过SQL语句操做数据库并处理相应数据 //6.1 新建用户名为abcdef,密码为123456的记录 mysql_query(myData, "insert into TestTable value(‘abcdef’,’ 123456’)"); //6.2 显示全部记录 mysql_query(myData, "select * from TestTable"); //6.3 将查询结果保存到res中 res = mysql_store_result( myData ) ; //6.4 逐条显示记录 int j = 0; while ( row = mysql_fetch_row( res ) ) {//获取一条记录 j = mysql_num_fields( res ) ;//获取每条记录的字段数 for ( k = 0 ; k < j ; k++ ) { printf( “%s”, row[k] ) ; printf( “\n”) ; } } //6.5 释放res mysql_free_result( res ) ; //7. 检查数据库链接是否有效,当且仅当设置了MYSQL_OPT_RECONNECT选项有效 unsigned long qwPreId = mysql_thread_id( myData );//重连以前的id mysql_ping( myData ); unsigned long qwNextId = mysql_thread_id( myData );//重连以后的id //8. 关闭数据库链接 mysql_close( myData ); //9. 结束MySQL库 mysql_thread_end();
(1) 初始化多个connection,每一个connection包含数据库初始化和关闭,链接池采用单例模式安全
(2) 选取connection,异常返回空数据结构
(3) 关闭多个connection并回收链接池资源多线程
链接池可参考:http://www.oschina.net/code/snippet_583625_19818#32990函数