1 引言
随着社会信息化的深入,数据库在社会各个领域被广泛应用。在这些数据库应用项目开发过程中,需要做两方面的决策:1. 使用何种数据库软件;2. 采用何种方式访问数据库。数据库软件的选择面比较宽,在目前众多商业数据库软件中,SQL SERVER 和ORACLE被较多的使用,当然这两个数据库软件的价格也较昂贵,本文选择可免费使用的MySQL数据库社区版本,MySQL库属于开源数据库,具有较 高的成熟度和可靠性。数据库的访问方式有很多,可以使用ODBC、DAO、ADO等方法,这些方法简单直接但是效率不高,不适合大型复杂的系统使用,例如 网络游戏的数据库系统开发需要考虑同时大量的数据库访问,因此访问的效率非常重要。基于C程序语言的高效率,使用C API访问数据库可以提高数据库的访问效率。基于以上两点,本文将介绍基于C API的MySQL数据库访问方法,给出在单线程和多线程程序环境下的具体代码和分析。
2 建表
为了方便说明数据库的访问,先建立一个数据库表TestTable,可以使用SQL语句创建该表,也可以使用MySQL提供的图形界面来创建。数据库表中字段如下:
该数据库表使用最常见的用户名和密码作为字段,本文将通过该表来实现不同程序环境下基于C API的数据库的访问方法。
3 单线程程序的数据库访问
单线程应用程序访问MySQL数据库相对简单,其过程包含以下几步:
(1)初始化MySQL库
(2)初始化数据库连接句柄
(3)连接数据库
(4)通过SQL语句操作数据库并处理相应数据
(5)关闭数据库连接
(6)结束MySQL库
通过这五个步骤即可实现数据库的访问,具体代码和分析如下:
//在main主函数中添加代码
//1.定义访问数据库所需变量
MYSQL * myData;
MYSQL_RES * res;
MYSQL_ROW row;
//2. 初始化MySQL库和数据库连接句柄
myData = mysql_init((MYSQL*) 0);
//3. 连接数据库,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 )
//4.1新建用户名为abcdef,密码为123456的记录
mysql_query(myData, "insert into TestTable value(‘abcdef’,’ 123456’)");
//4.2显示所有记录
//查询所有记录
mysql_query(myData, "select * from TestTable");
//将查询结果保存到res中
res = mysql_store_result( myData ) ;
//逐条显示记录
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”) ;
}
//释放res
mysql_free_result( res ) ;
//5. 关闭数据库连接
mysql_close( myData );
//6. 结束MySQL库
mysql_library_end();
关于代码的几点说明:
(1)定义变量中的三个数据结构为访问MySQL所需,MYSQL结构表示一个数据库连接的句柄,其中包含了数据库连接所需的参数,MYSQL_RES结构表示数据库访问中一个查询的返回结果,MYSQL_ROW结构表示返回结构中的一条记录;
(3)在单线程时,步骤初始化MySQL库和数据库连接句柄可合并, 由mysql_init()来处理。该函数会自动调用函数mysql_library_init()来初始化MySQL库,同时初始化连接句柄。
4 多线程环境下的数据库访问
多线程环境下的数据库访问需要保证线程安全。Windows版本的MySQL C API函数都是线程安全的,除了mysql_library_init(),而我们刚才的代码中使用的mysql_init()函数会自动调用函数 mysql_library_init()来初始化MySQL库,因此在多线程环境下,需要不同的初始化代码和清理代码。具体过程如下:
(2)启动各数据库访问线程
(3)主函数等待各个线程的结束
(4)调用mysql_library_end ()清理MySQL库。
其中数据库访问线程的代码和单线程数据库访问代码类似,但是需要如下变化:
(1)单线程中的第2步初始化MySQL库和数据库连接句柄,不能再使用mysql_init(),代码应作如下修改:
//初始化线程
my_init();
mysql_thread_init();
//初始化myData
myData = malloc(sizeof(MYSQL));
memset(&myData, 0, sizeof(MYSQL))
(2)上述初始化myData,只是将myData所有成员设为0,如果有需要可以根据具体情况设置该结构成员的值,例myData->reconnect= 1,其作用是设置数据库连接属性为重连接,即当数据库连接断开时,自动重新连接;
5 总结
综上所述,使用C API访问MySQL数据库在不同线程环境下的区别主要在于初始化和访问结束后清理代码,也就是说除了初始化和清理代码,MySQL提供给我们的C API函数都是线程安全的。最后需要有一点说明,使用C API访问数据库可以提高数据库的访问效率,但并不是所有的数据库项目都适合这种方式,该方式适合需要大量实时并发处理的数据库项目,例如网络游戏的数据 库项目,对于有此需求的数据库项目可参考本文。