(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函數