Linux下 C++ 操作 MySQL


一、安裝 MySQL的 C/C++ API

sudo apt-get install mysql-server libmysql++-dev;
// 安裝 MySQL的 C/C++ API

sudo cp /usr/lib/mysql/* /usr/lib/
// 將頭文件複製到 C/C++ 的頭文件目錄(這樣子纔可以調用頭文件)

安裝好 API 之後,有了頭文件,就可以調用關於 MySQL 操作的函數接口 來使用了。

注意,要操作 MySQL,需要先打開 MySQL 服務纔有用


二、常用 MySQL API 的數據類型

2.1、MYSQL

用於定義一個 mysql 對象,便於後續操作確定要操作的數據庫是哪一個。

MYSQL mysql;  
// mysql標記對應某個數據庫

2.2、MYSQL_ROW

用於定義一個行對象,其內容含有一行的數據。(比如說 SELECT 返回結果就是 多行數據,然後通過函數調用,我們就可以一行一行獲取)

MYSQL_ROW row;  
// 一行裏面 包括多個字段
// row[i] 可用於輸出該行 對應於 第i個字段(列)的數據

2.3、MYSQL_FIELD

用於定義一個存儲字段信息的對象。

MYSQL_FIELD *field;  
// field->name 存儲對應字段名稱(一個結構體,其中應該還有其他字段信息)

2.4、MYSQL_RES

用於定義一個存儲數據庫檢索信息結果的對象

MYSQL_RES *result;

三、常用的 MySQL API 函數介紹

其實在操作mysql數據庫時,最常使用的函數有以下幾個:

3.1、mysql_init()

用於初始化一個 MYSQL (類型)對象,來連接 mysql 服務端。

MYSQL *mysql_init( MYSQL *mysql );
// 返回值:若成功,返回值 是 MySQL 對象(這個也保存在 輸入參數中);若出錯,返回 NULL
// 因爲 返回值 和 輸入參數 都記錄有 MySQL 對象,所以一般直接用輸入參數(返回值就驗證是不是 == NULL 即可)

// 例子:
MYSQL mysql;
mysql_init( &mysql );

3.2、mysql_real_connect()

用於連接數據庫

MYSQL *mysql_real_connect (
    MYSQL *mysql,   // mysql_init()初始化的MYSQL對象,作爲輸入
    const char *host,   //主機地址
    const char *user,   //用戶,例如:root
    const char *passwd,   //數據庫的密碼
    const char *db,   //要連接的數據庫,例如:student
    unsigned int port,   //端口,可填0
    const char *unix_socket,   //一般爲NULL
    unsigned long client_flag);  //一般爲0
// 連接的時候,需要連接到 MySQL 服務器,需要 IP、用戶名、密碼、連接到哪個數據庫等信息。
// 返回值,若失敗,返回 NULL
// 如果成功,其返回值 和 輸入的第一個參數一樣,此時這個 MySQL 對象就是對應的 那個連接上 的 庫


// 例子
mysql_real_connect( &mysql, "localhost", "root", 
                    "123456", "student", 0, NULL, 0 );

3.3、mysql_query()

用於執行mysql命令。其參數應使用c風格字符串。

mysql_query( MYSQL *mysql, char * command );

// 例子
string command = "select * from info";
mysql_query( &mysql, command.c_str() );

其實就是,當我們自己直接操作 MySQL 的時候,就是用來 MySQL 的指令,比如查詢 SELECT。那麼用 C++ 調用 API,這裏輸入的 command 相當於就是 我們要想通過 C++ 去讓 MySQL 做什麼行爲。

因爲直接函數操作連接的對象(MYSQL 那個數據類型的對象是 庫)是 庫,但是具體數據是在 表,因此一般先 得到這個 庫的表(或者已經知道是哪個表了,要先得到,可以先 show tables 的 MySQL 指令,然後通過獲取其中一個,就是作爲了 字符串,我們要處理的 表名),然後具體再操作這個表,比如要查詢表中信息,如 SELECT * from 表名 作爲 這個函數的 參數,就可以的

3.4、mysql_store_result()

用於獲取mysql操作的檢索結果。

也就是,先通過 mysql_query() 獲取檢索對象(MYSQL *mysql),然後再利用這個函數來處理,從而獲取 檢索對象中 實際的數據結果。

MYSQL_RES *mysql_store_result(MYSQL *mysql);
// 返回值:若成功,返回的對象,就是存儲數據庫檢索信息結果的對象;若出錯,返回 NULL

// 例子
MYSQL_RES *result;
result = mysql_store_result( &mysql );

3.5、mysql_num_rows()

用於獲取結果集的行數。(也就是檢索結果中的數據,有多少行)

int mysql_num_rows( MYSQL_RES *result );
// 返回值,檢索結果的行數。(無結果那就是 0)

3.6、mysql_num_fields()

用於獲取結果集的字段數。(也就是有多少列,有幾個字段)

int mysql_num_fields( MYSQL_RES *result );
// 返回值,字段的個數。

//example
int fieldcount;
fieldcount = mysql_num_fields( result );

3.7、mysql_fetch_field()

用於獲取結果集中,下一個字段的信息(對象保存着字段的信息,其中包括有 字段名,字段的數據類型等)。

MYSQL_FIELD* mysql_fetch_field(MYSQL_RES *result);
// 返回值:返回結果集中下一個字段信息。如果結束了,就是字段信息都獲取完了,那就是 NULL

// 獲取字段信息的時候,就是用一個循環,直到爲 NULL

3.8、mysql_fetch_row()

從結果集中獲取下一行,結束返回NULL。(一行一行獲取結果集中的數據)

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result); 

// 例子
// 其中 num 是前面,統計着有幾個字段。一行的數據就是 包含着 這麼多個字段的數據
// 先通過獲取一整行 row,然後 再獲取這一行中,對應每個字段的具體信息,
MYSQL_ROW row;
while( (row = mysql_fetch_row( result )) != NULL ) {
    for( int i = 0; i < num; i++ ) {
        cout << row[i] << "\t\t";
    }
    cout << endl;
}

3.9、mysql_fetch_field_direct()

給定字段序號,返回字段類型,結束返回NULL。(獲取第 i 個字段的字段信息)

MYSQL_FIELD* mysql_fetch_field_direct(MYSQL_RES *result, int i);
// 返回值,是 字段的信息,包括着字段名,字段數據類型等等

//example
int num = mysql_num_fields( result );  //返回字段個數
for( int i = 0; i < num; i++ ) {
    field = mysql_fetch_field_direct( result, i );  //返回字段類型
    cout << field->name << "\t\t";  //輸出字段名
}
cout << endl;

3.10、mysql_close()

用於關閉連接。

連接完,處理完,就關閉 MySQL 連接(和處理完文件信息後,關閉文件流一樣)

mysql_close( MYSQL *mysql );

四、示例代碼

#include <iostream>
#include <string>
#include <mysql/mysql.h>
using namespace std;

// 通過建立一個 操作數據庫 的類,後面就每操作具體的一個數據庫,我們就實例化一個 對象,這樣子就很方便了
// 類 可以寫在 另一個 .h 頭文件,實現在另一個 .cpp 中,然後增加到頭文件就可以
class MysqlDB {
private:
    // 要用到的幾個數據類型
    MYSQL mysql;     // 操作的 數據庫對象
    MYSQL_ROW row;   // 獲取一行的數據信息
    MYSQL_RES *result;  // 檢索的結果集
    MYSQL_FIELD *field;  // 字段的信息,如 字段名、字段的數據類型等
public:
    // 構造函數,用於初始化,初始化對象
    MysqlDB() {
        if( mysql_init( &mysql ) == NULL ) {
            cout << "init error, line: " << __LINE__ << endl;
            exit(-1);
        }
    }
    // 析構函數,那就用於,關閉 MySQL 連接
    ~MysqlDB() {
        mysql_close( &mysql );
    }
    
    // 成員函數:用於連接 到數據庫 中,重要的幾個參數(定義是 string,但是要轉化到 C 的 str)
    void connect( string host, string user, string passwd,  string database ) {
        if( !mysql_real_connect( &mysql, host.c_str(), user.c_str(), passwd.c_str(), 
                                    database.c_str(), 0, NULL, 0 ) ) {
            cout << "connect error, line: " << __LINE__ << endl;
            exit(-1);
        }
    }
    // 還可以繼續定義其他成員函數,用於實現 更多的功能
    void add();
    void print();
};

// 給 表 info 插入輸入的信息
// 這裏表名,默認知道,如果不知道,我們可以先通過 定義一個成員函數,先獲取 庫中,所有的表
// 這樣子,表名 也可以定義成一個 string,用於我們的具體選擇
void MysqlDB::add() {
    string id, name, sex, birthday;
    do {
        cout << "請輸入學生信息:\n";

        cin >> id >> name >> sex >> birthday;
        string sql = "INSERT INTO info VALUES('" + id + "', '" + name + 
                        "', '" + sex + "', '" + birthday + "');";

        mysql_query( &mysql, sql.c_str() );
        cout << "是否繼續(y/n): ";
        cin >> id;
    } while( id == "y" );
}

// 將查詢到的結果,打印顯示出來
void MysqlDB::print() {

    // string sql = "select * from info where name = '" + name + "';";  //要有''
    string sql = "select * from info;";
    mysql_query( &mysql, sql.c_str() );

    result = mysql_store_result( &mysql );
    if( !result ) {
        cout << "result error, line : " << __LINE__ << endl;
        return ;
    }

    int num;
    num = mysql_num_fields( result );  //返回字段個數
    for( int i = 0; i < num; i++ ) {
        field = mysql_fetch_field_direct( result, i );  //返回字段類型
        cout << field->name << "\t\t";  //輸出字段名
    }
    cout << endl;

    while( row = mysql_fetch_row( result ), row ) {
        for( int i = 0; i < num; i++ ) {
            cout << row[i] << "\t\t";
        }
        cout << endl;
    }
}

// main 函數中
int main() {
    // 定義成類之後,要操作一個 庫,就實例化一個對象即可,而且函數功能也封裝好了,直接使用就可以

    MysqlDB db;   // 實例化成對象
    
    // 然後連接
    db.connect( "localhost", "root", "niliushall", "student" ); 
    
    // 先打印,增加數據,再打印
    db.print();
    db.add();
    db.print();

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章