目錄
一、準備
????????測試
二、創建對象
三、連接Mysql服務
四、下達指令
? ? ? ? 3.1增刪改
? ? ? ? ? ? ? ? 增加
編碼格式
? ? ? ? ? ? ? ? 刪除
? ? ? ? ? ? ? ? 修改
? ? ? ? 3.2查詢結果
????????結構體理解
????????打印屬性
????????打印數據
????????前面我們已經學習并練習了本地命令行形式的sql語句的使用,可在以后開發中我們一般
不會直接命令行操作數據庫,今天我們認識如何在自己的代碼中調用指令對數據庫進CURD操作。
所有操作函數均可以在mysql.com官方中查到使用手冊
一、準備
使用c或其他語言操作數據庫我們需要下載對應的第三方庫,并把我們需要的頭文件和庫路徑添加到對應程序編譯鏈接時的查詢位置。下載我們可以去官網下載。https://dev.mysql.com/downloads/
主要使用mysql.h文件:
庫需要遠程連接:
一般在/usr/lib64/libmysqlclient.so.20
或者在/lib64/libmysqlclient.so.20
我的在下面位置
????????測試
#include<iostream>
#include<mysql/mysql.h>int main()
{std::cout << "mysql test : " << mysql_get_client_info() << std::endl;return 0;
}
若能運行成功看到mysql版本就說明準備完成
二、創建對象
MYSQL * mysql_init(MYSQL*mysql)
eg:MYSQL*mfp = mysql_init(nullptr);返回:NULL if there was insufficient memory to allocate a new object.與mysql_close(MYSQL *)搭配使用,與打開關閉文件類似,防止空間浪費泄露
三、連接Mysql服務
申請完對象我們就可以連接mysql服務了。
首先我們要創建我們要連接的mysql服務用戶,不要直接使用root用戶,注意千萬不要把mysql的端口暴露在公網中,這里只是測試,用完請立即刪除,避免遭到攻擊!!!
MYSQL *mysql_real_connect(MYSQL *mysql, --創建的mysql對象句柄const char *host, --連接的用戶const char *user, --連接的主機const char *passwd, --連接所需的密碼const char *db, --訪問哪個庫unsigned int port, --訪問的端口const char *unix_socket, --域間套接字直接設為null unsigned long client_flag); --標記為設為0返回:A MYSQL* connection handler if the connection was successful, NULL if the connection was unsuccessful. For a successful connection, the return value is the same as the value of the first argument.
四、下達指令
????????連接成功后我們就可以利用相關語句執行我們的操作,由于select與其他操作不同所以分開描述
????????準備測試表:
int mysql_query(MYSQL *mysql,const char *stmt_str)mysql是我們申請的mysql對象,stmt_str是我們要操作的sql語句返回:Zero for success. Nonzero if an error occurred.
? ? ? ? 3.1增刪改
? ? ? ? ? ? ? ? 增加
const char* sql = "insert into user values(1,'peter',18)";int n = mysql_query(mfp,sql);if(n == 0){std::cout << "query sucessed: " << sql << std::endl;}else{std::cerr << "query failed: " << mysql_error(mfp) << std::endl;return 1;}
編碼格式
? ? ? ? ? ? ? ? 刪除
刪除編碼格式錯誤的數據
? ? ? ? ? ? ? ? 修改
? ? ? ? 3.2查詢結果
若我們直接查發現并沒有任何數據回顯,顯然直接query拿不到查詢結果
為了拿到和命令行一樣的數據顯示,mysql提供了一塊空間用來儲存獲取的結果,并通過一些函數獲得數據
? ? ?
MYSQL_RES *mysql_store_result(MYSQL *mysql)
將結果放在MYSQL_RES *的結構體中返回:A pointer to a MYSQL_RES result structure with the results. NULL if the statement did not return a result set or an error occurred.搭配void mysql_free_result(MYSQL_RES *result)進行空間的獲取與釋放
上面代碼僅成功把結果放在了res結構體中,但我們還要打印才能拿到數據
????????結構體理解
對于上圖結構體我們可以看到其中的字段均是指針類型,本質還是指向一個結構體
對于這種指向我們可以把它抽象成一個獨特的二維數組進行理解,如圖:
所以我們在打印數據時也可以利用行列數和[下標]進行數據訪問
????????打印屬性
獲取二維數組列數my_ulonglong mysql_num_fields(MYSQL_RES*res)獲取列屬性內容MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES* res)
//打印列int field_count = mysql_num_fields(res);std::cout << "列數:" << field_count << std::endl;MYSQL_FIELD *field = mysql_fetch_fields(res);for(int i = 0; i < field_count; i++){std::cout << field[i].name << " ";}std::cout << std::endl;
????????打印數據
獲取二維數組行數
my_ulonglong mysql_num_rows(MYSQL_RES*res)獲取內容
MYSQL_ROW * mysql_fetch_row(MYSQL_RES*res)
返回:一個數據結構體
//打印列int field_count = mysql_num_fields(res);int row_count = mysql_num_rows(res);std::cout << "行數:" << row_count << std::endl;std::cout << "列數:" << field_count << std::endl;MYSQL_FIELD *field = mysql_fetch_fields(res);for(int i = 0; i < field_count; i++){std::cout << field[i].name << " ";}std::cout << std::endl;//打印數據(行)for(int i = 0; i < row_count; i++){MYSQL_ROW row = mysql_fetch_row(res);for(int j = 0; j < field_count; j++){std::cout << row[j] << " ";}std::cout << std::endl;}
代碼;
#include<iostream>
#include<mysql/mysql.h>const char*host = "localhost";
const char*user = "con";
const char*password = "123456";
const char*database = "conn";
const unsigned int port = 3306;int main()
{// std::cout << "mysql test : " << mysql_get_client_info() << std::endl;MYSQL* mfp = mysql_init(nullptr);if (mfp == nullptr) {std::cerr << "申請mysql對象失敗" << std::endl;return 1;}std::cout << "申請成功" << std::endl;MYSQL* conn = mysql_real_connect(mfp, host, user, password, database, port, nullptr, 0);if(conn == nullptr){std::cerr << "連接數據庫失敗" << std::endl;return 1;}std::cout << "連接成功" << std::endl;// //測試看是否連接成功// while(true)// {}//執行sql語句//統一編碼格式mysql_set_character_set(mfp, "utf8");// const char* sql = "insert into user values(1,'peter',18)";// const char* sql = "insert into user values(2,'jimmy',19)";// const char* sql = "insert into user values(3,'張三',20)";// const char* sql = "delete from user where id=3";// const char* sql = "update user set age=21 where id=2";const char* sql = "select * from user";int n = mysql_query(mfp,sql);if(n == 0){std::cout << "query sucessed: " << sql << std::endl;}else{std::cerr << "query failed: " << mysql_error(mfp) << std::endl;return 1;}//獲取結果集MYSQL_RES* res = mysql_store_result(mfp);if(res == nullptr){std::cerr << "獲取結果集失敗" << std::endl;return 1;}std::cout << "獲取結果集成功" << std::endl;//打印列int field_count = mysql_num_fields(res);int row_count = mysql_num_rows(res);std::cout << "行數:" << row_count << std::endl;std::cout << "列數:" << field_count << std::endl;MYSQL_FIELD *field = mysql_fetch_fields(res);for(int i = 0; i < field_count; i++){std::cout << field[i].name << " ";}std::cout << std::endl;//打印數據(行)for(int i = 0; i < row_count; i++){MYSQL_ROW row = mysql_fetch_row(res);for(int j = 0; j < field_count; j++){std::cout << row[j] << " ";}std::cout << std::endl;}mysql_free_result(res);mysql_close(mfp);return 0;
}