1、首先當然是串連資料庫,函數原型如下:
MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,const char *user,const char *passwd,const char *db,unsigned int port,const char *unix_socket,unsigned long clientflag);
第一個參數 MYSQL是 C api中一個非常重要的變數,裡面記憶體非常豐富,有port,dbname,charset等串連基本參數。它也包含了一個叫 st_mysql_methods的結構體變數,該變數裡面儲存著很多函數指標,這些函數指標將會在資料庫連接成功以後的各種資料操作中被調用。mysql_real_connect函數中各參數,基本都是顧名思意。
2、串連資料庫成功之後就可以執行sql語句了使用mysql_query
int STDCALL mysql_query(MYSQL *mysql, const char *q);
第一個參數上面已經介紹過,第二個參數為要執行的sql語句。
這個函數總體就兩步:
(1)發送sql語句,其實就一個socket發送sql 語句,加上mysql固定的協議頭。懶的去看源碼了,抓了下包,如下:
0000 19 00 00 00 0373 65 6c 65 63 74 20 61 70 70 5f .....select app_
0010 6e 61 6d 65 20 66 72 6f 6d 20 61 70 70 name from app
紅色部分是協議,前面兩位其實就是包的長度。具體協議沒研究過。
(2)然後就是接受結果,這裡將會調用MYSQL變數中的st_mysql_methods中的read_query_result函數指標
3、擷取結果
sql執行完以後,如果是查詢語句,我們當然還要讀取資料,如果update,insert等語句,那麼就看下操作成功與否即可。我們來看看如何擷取查詢結果: 如果mysql_query返回成功,那麼我們就通過mysql_store_result這個函數來讀取結果。原型如下:
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
該函數會調用MYSQL變數中的st_mysql_methods中的 read_rows函數指標來擷取查詢的結果。同時該函數會返回MYSQL_RES 這樣一個變數,該變數主要用於儲存查詢的結果。同時該函數malloc了一片記憶體空間來儲存查詢過來的資料,所以我們一定要記的 free(result),不然是肯定會造成記憶體流失的。 執行完mysql_store_result以後,其實資料都已經在MYSQL_RES 變數中了,下面的api基本就是讀取MYSQL_RES 中的資料。例如mysql_fetch_row這個函數,就是讀去查詢結果的一行。函數原型如下
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
它會返回一個MYSQL_ROW變數,MYSQL_ROW其實就是char **.就當成一個二維數組來用吧。還有很多api,不再一一介紹,大部分資訊都在MYSQL_RES MYSQL這兩個結構體中。具體可以參考mysql官方網站: http://dev.mysql.com/doc/refman/5.1/en/c.html 突然發現官方網站資料好全面,貌似比任何書都要好。
下面來個例子:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<mysql/mysql.h>#define MAX_COLUMN_LEN 32int main(int argc , char *argv[]){ MYSQL my_connection; MYSQL_RES *result; MYSQL_ROW sql_row; MYSQL_FIELD *fd; char column[MAX_COLUMN_LEN][MAX_COLUMN_LEN]; int res; mysql_init(&my_connection); if(mysql_real_connect(&my_connection,"127.0.0.1","使用者","密碼","資料名稱",3306,NULL,0)) { perror("connect"); res=mysql_query(&my_connection,"select * from app");//查詢 if(!res) { result=mysql_store_result(&my_connection);//儲存查詢到的資料到result if(result) { int i,j; printf("the result number is %lu\n ",(unsigned long)mysql_num_rows(result)); for(i=0;fd=mysql_fetch_field(result);i++)//擷取列名 { bzero(column[i],sizeof(column[i])); strcpy(column[i],fd->name); } j=mysql_num_fields(result); for(i=0;i<j;i++) { printf("%s\t",column[i]); } printf("\n"); while(sql_row=mysql_fetch_row(result))//擷取具體的資料 { for(i=0;i<j;i++) { printf("%s\t",sql_row[i]); } printf("\n"); } } } else { perror("select"); } } else { perror("connect:error"); } mysql_free_result(MYSQL_RES *result);//釋放結果資源 mysql_close(&my_connection);//中斷連線}
上面這個例子就是從一個表中查資料,然後輸出。 如果要insert或者update,只需要修改具體的sql既可。具體的操作都是通過mysql_query這個函數來搞定。 現在來講編譯的方法吧,這裡我們需要.h以及.so庫。我們可以在 http://dev.mysql.com/downloads/connector/c/6.0.html 下載Connector/C。簡單的方法就是: 把裡面include的東西拷貝到/usr/include/mysql/下面去,這樣編譯的時候就不需要加-I了,然後把lib下面的東西拷貝的/usr/lib/下去。
gcc具體的編譯方法:gcc ***.c -o *** -lmysqlclient