文章目錄
C_API(簡單的)
# MYSQL C_API結構體
- MYSQL 數據庫連接的類型,代表一個mysql連接
- MYSQL_RES 查詢返回的結果集,返回的多條數據構成的內存結構 不僅包含返回的二維的字符串數組 還有一些元數據信息
- MYSQL_ROW 一行記錄,字符串數組, row[0],...row[n-1]
- MYSQL_ROWS 由 MYSQL_ROW 構成的鏈表函數
- mysql_init 初始化數據庫連接,并沒有建立連接1.傳NULL,會自動分配地址,初始化之后返回2.如果有指針對象,返回的還是原來的地址
- mysql_close 釋放數據庫連接
- mysql_error 顯示錯誤信息,字符串顯示
- mysql_real_connect 建立數據庫連接,TCP套接字
- mysql_query 執行最簡單的sql語句;insert update DELETE select
- mysql_store_result 加載結果集,查詢語句之后使用,使用緩存在內存中會存儲一份
- mysql_use_result 加載select結果集
- mysql_free_result 釋放結果集
- mysql_num_rows 結果集中的元數據:行數
- mysql_num_fields 結果集中的元數據:列數
- mysql_fetch_row 從結果集獲得一行數據
- mysql_insert_id 獲得插入記錄自動生成的id
用戶發送請求,程序通過端口監聽用戶的,程序中會包含一系列的操作來訪問數據庫,但是mysql官方為我們封裝好了一系列的函數,我們可以通過函數來對mysql服務器進行訪問,獲得結果,對數據進行一系列的處理,然后返回給用戶。
安裝這個庫
locate mysql.hlocate libmysqlclient.so
只包含頭文件但是主要的代碼在動態庫中,所以在編譯的時候要將動態庫進行鏈接。
使用流程
可以類比mysql自帶客戶端
# 給mysql的服務器的監聽端口,發送信息,建立連接,
mysql -u root -p123456# 操作完成會進入mysql的客戶端,就可以給服務器發送sql語句對數據進行操作。
初始化連接
mysql_init
建立連接
mysql_real_connect
執行SQL語句
mysql_query
當一個連接,建立好之后可以查詢多次。
處理結果
mysql_store_result
適用于數據量較小的情況。會在內存申請空間。在內存中存儲一份。
注意:經驗又是沒有返回結果也不會返回null,所以最好拿到返回結果之后做一下判斷,如果是null,就是沒有返回數據,如果不是null,使用mysql_num_rows()函數,判斷是不是0,如果不是0,就進行常規的后續操作。
msyql_use_result
mysql_num_rows
msyql_free_result
mysql_num_fields
mysql_fetch_row
獲取一行數據的信息
拿到的數據庫的存儲形式:
多線程安全
假如同一個進程中,有多個線程,如果我多個線程用來訪問一個靜態資源不會出現問題,但是現在我要沒有線程與mysql服務器都建立一個連接,然后他們都進行訪問同一動態資源,都調用mysql_init()函數,雖然unbantu說這個事線程安全函數(也就是說這個函數在設計的時候有加鎖)但是并不是這樣的,同時調用mysql_init函數可能會出現兩個線程拿到的是同一個連接,然后用于查詢的時候返回數據,接收數據的時候會出現數據讀取錯誤,但是我們不對mysql_init(),這個函數就行加鎖操作,我們不能對庫函數進行修改,但是我們可以自己封裝一個函數,這個函數的主要作用就是加鎖,執行庫函數,然后解鎖操作,來保證多線程的安全。
關閉連接
mysql_close()
檢驗API是否出錯
mysql_error
#include <mysql/mysql.h>
#include <stdio.h>int main(void)
{//初始化連接MYSQL *mysql = mysql_init(NULL);//mysql 返回值要接收 就是初始化好的結構體指針// MYSQL *mysql = NULL;// mysql = mysql_init(mysql);//使用庫中的檢驗錯誤的函數 mysql_errorprintf("%s\n", mysql_error(mysql));// 建立到mysql服務器的連接 并且發送賬號密碼mysql_real_connect(mysql, "localhost", "root", "123456", "test_connect", 0, NULL, 0);printf("%s\n", mysql_error(mysql));//上面連接已經建立,賬號密碼已經驗證 -> 發送sql語句給mysql服務器// mysql_query(mysql, "insert into class values(NULL, 3)");//刪除數據mysql_query(mysql, "delete from class where id=6");//使用完成只之后要關閉連接mysql_close(mysql);return 0;
}
mysql> select * from class;
+----+------------+
| id | class_name |
+----+------------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------------+
3 rows in set (0.01 sec)
#include <mysql/mysql.h>
#include <stdio.h>int main(void)
{//初始化連接MYSQL *mysql = mysql_init(NULL);//mysql 返回值要接收 就是初始化好的結構體指針// MYSQL *mysql = NULL;// mysql = mysql_init(mysql);//使用庫中的檢驗錯誤的函數 mysql_errorprintf("%s\n", mysql_error(mysql));// 建立到mysql服務器的連接 并且發送賬號密碼mysql_real_connect(mysql, "localhost", "root", "123456", "test_connect", 0, NULL, 0);printf("%s\n", mysql_error(mysql));//只要是執行select sql語句,必須接收返回值,并且釋放//因為如果不接收返回值,下一次接收可能會接收到上一次的數據,導致數據錯亂 //發送sql語句mysql_query(mysql, "select * from class");//通過mysql_store_result()函數獲取mysql_query的返回值MYSQL_RES * res = mysql_store_result(mysql);//加返回值的驗證if(mysql_num_rows(res) != 0){//對數據進行處理MYSQL_ROW row;//從結果集中拿出一行,如果結果集中沒有更多數據或結果集為空,則返回NULLwhile((row = mysql_fetch_row(res))){unsigned int colunm;colunm = mysql_num_fields(res);for(int i = 0; i < colunm; i++){printf("%s ", row[i]);}printf("\n");}}mysql_free_result(res);//使用完成只之后要關閉連接mysql_close(mysql);return 0;
}
mysql> select * from class;
+----+------------+
| id | class_name |
+----+------------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 3 |
| 5 | 3 |
+----+------------+
5 rows in set (0.00 sec)