MySql 基于C_API的数据库封装

1. 单线程程序的数据库访问  

        (1)初始化MySQL库 
  (2)初始化数据库连接句柄 
  (3)连接数据库 
  (4)通过SQL语句操作数据库并处理相应数据 
  (5)关闭数据库连接 
  (6)结束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() 来释放未被释放的内存,否则会出现内存泄漏

2. 多线程环境下的数据库访问 

  多线程环境下的数据库访问需要保证线程安全。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();

3. 连接池

    (1) 初始化多个connection,每个connection包含数据库初始化和关闭,连接池采用单例模式

    (2) 选取connection,异常返回空

    (3) 关闭多个connection并回收连接池资源

    连接池可参考:http://www.oschina.net/code/snippet_583625_19818#32990

转载于:https://my.oschina.net/shou1156226/blog/752337

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值