亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MySQL中C接口的實現

 更新時間:2025年09月28日 10:21:57   作者:綿陽的腦內SSD  
本節(jié)內容介紹使用C/C++訪問數據庫,?包括對數據庫的增刪查改操作,主要是學習一些接口的調用,具有一定的參考價值,感興趣的可以了解一下

前言:本節(jié)內容介紹使用C/C++訪問數據庫, 包括對數據庫的增刪查改操作。 主要是學習一些接口的調用, 廢話不多說, 開始我們的學習吧!

ps:本節(jié)內容比較容易, 友友們放心觀看哦!

準備mysql庫

其實我們訪問mysql不只是使用命令行進行訪問, 我們未來訪問數據庫一定是一個程序對數據庫進行訪問, 而程序其實就是代碼。所以未來我們可以使用代碼來訪問數據庫, 這里我們使用C/C++代碼對數據庫進行訪問。

首先我們創(chuàng)建一個非root級別用戶和一個數據庫:

然后我們要知道, 我們訪問數據要有對應的開發(fā)包, 這些開發(fā)包我們可以直接在apt里面找到下載安裝。

sudo apt install -y libmysqlclient-dev

安裝好了之后我們就能在/usr/include/路徑下面看到mysql目錄

這個 里面包含著我們需要的文件, 像什么mysql.h就是我們所需要的。

然后在/usr/lib/x86_64-linux-gnu里面也有我們的mysql的連接庫:

使用mysql庫

編譯文件

然后使用庫,系統(tǒng)會默認搜索的路徑是/lib/include路徑, 然后我們要使用的mysql.h頭文件在/lib/include西面的/mysql目錄下面, 所以我們包含頭文件要使用mysql/mysql.h:

#include<mysql/mysql.h>  

mysql_get_client_info函數可以打印當前mysql的版本信息。 

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

int main()
{
    cout << "mysql_client version: " << mysql_get_client_info() << endl;       
    return 0;
}

然后編譯可能會出現問題:

這是因為因為我們編譯的時候系統(tǒng)找不到鏈接的庫, 所以需要我們使用-l指令指定路徑:

 -lmysqlclient;

然后就能運行成功了:

官方API文檔

然后就是我們要對數據庫進行增刪查改,我們可以去mysql的官方文檔進行查看對應的資料

先進入官方網站,點擊文檔:

然后下滑找到并點擊C API:

然后點擊function就能看到我們常用的一些函數了:

知道了這些之后, 下面開始學習增刪查改:

對象的創(chuàng)建和關閉

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

int main()
{
    MYSQL* my = mysql_init(nullptr);
    if (nullptr)
    {
        cerr << "init MySQL error" << endl;
        return 1;
    }
    
    mysql_close(my);
    return 0;
}

這里面的MYSQL類型就類似于我們C語言里面的FILE類型, 都是一個句柄。如果成功了就是返回一個非空的值, 就代表我們獲得了拒柄。 

既然獲得句柄, 那么最后情況下還要關閉數據庫, 釋放一系列資源。 使用mysql_close函數, 就類似于我們關閉文件的操作。

鏈接數據庫

在官方文檔中給出的mysql鏈接函數如下。 

MYSQL *
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 client_flag)

其中的第一個參數就是我們剛剛獲取的句柄。 然后第二個參數就是登錄的mysql所在的ip地址, 這里我們采用本地環(huán)回;  第三個參數就是就是使用的用戶名; 第四個參數就是對應用戶的密碼; 第五個參數就是數據庫的名稱;第六個參數就是端口號;剩下的參數默認即可。返回值就是MYSQL*也就是句柄, 如果是nullptr就是連接失敗。

#include<iostream>
#include<mysql/mysql.h>  
#include<string>
using namespace std;
const string host = "localhost";
const string user = "mian_yang";
const string passwd = "XXXXXXXXXXXXXXXX";
const string db = "school_book_manage";
const unsigned int port = 3306;

int main()
{
    MYSQL* my = mysql_init(nullptr);
    if (nullptr)
    {
        cerr << "init MySQL error" << endl;
        return 1;
    }
    //

    if (mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        cerr << "connect error" << endl;
        return 0;
    }
    //
    cout << "connect success" << endl;

    mysql_close(my);
    return 0;
}

然后我們編譯一下運行一下:

下達sql指令

然后我們就可以使用函數下達sql指令, 在官方文檔中給出的函數如下:        

int
mysql_query(MYSQL *mysql,
            const char *stmt_str)

其中第一個參數就是我們的句柄。 然后第二個參數就是我們要下達的指令。返回值如果為零就執(zhí)行成功了, 如果不為零, 就執(zhí)行失敗了。然后下面是代碼:

#include<iostream>
#include<mysql/mysql.h>  
#include<string>
using namespace std;
const string host = "localhost";
const string user = "mian_yang";
const string passwd = "MYhylk563_al36huz.6";
const string db = "school_book_manage";
const unsigned int port = 3306;



int main()
{
    MYSQL* my = mysql_init(nullptr);
    if (nullptr)
    {
        cerr << "init MySQL error" << endl;
        return 1;
    }
    //

    if (mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        cerr << "connect error" << endl;
        return 0;
    }
    //
    cout << "connect success" << endl;


    string sql;
    while (true)
    {
        cout << ">>";
        if (!getline(cin, sql) || sql == "quit") break;
        int n = mysql_query(my, sql.c_str());
        if (n == 0) 
        {
            cout << sql << "  success "<<endl;
        }
        else cout << sql << "  error" << endl;
    }

    mysql_close(my);
    return 0;
}

運行的時候我們就來測驗一下進行插入:

然后也可以看到我們的sql語句執(zhí)行成功了!

現在我們插入一下李四, 插入中文, 我們查看一下結果:

我們會看到李四被正常的插入進去了。 這里博主要說的是, 對于mysql8.0來說, 博主使用的是mysql8.0, 這里使用插入函數插入中文會正常插入。 但是如果是5.7版本的mysql, 那么這里如果插入中文插入的就是一堆亂碼。所有的亂碼問題都是客戶端和服務器雙方沒有形成編碼一致。比如說服務端使用utf8, 而客戶端使用的是其他的編碼方式。編碼不一致,那么我編碼使用的是utf8, 你解碼使用的是其他的方式。 那么就亂碼了。

這里我們的8.0數據庫, 表編碼都是utf8mb4的,說明我們的客戶端也是utf8mb4的。如果我們設置成其他的再插入就是一堆亂碼, 這里試驗一下:使用mysql_set_character_set函數設置解碼方式:

    mysql_set_character_set(my, "latin1");

插入成功: 

可以看到, 解碼出來就是一堆亂碼。

現在問題來了, 我們上面的插入試驗成功了, select語句呢? 我們的select語句是查, 要打印給我們一系列信息。 這里博主可以說一下實驗結果, 結果是執(zhí)行成功, 但是沒有打印結果。 其他的像update, delete操作都能執(zhí)行成功。 只有select 雖然執(zhí)行成功但是沒有給我們顯示信息, 這是因為其他的sql語句都只需要執(zhí)行成功即可, 但是select語句還要進行后續(xù)的處理, 比如打印。 所以select語句怎么處理呢? 

select語句

我們查出來的是一種表結構。 如果我們查出來有四條數據, 那么就有四行。 如果我們查出來的表有四列屬性, 那么查出來就有四列。 我們要知道我們要查的是一些數據。 那么這些數據在mysql內部就一定要有對應的內存空間保存這個數據。 mysql將所有的數據讀取出來的時候全部都當作字符串了。 然后有一個MYSQL_RES對象,MYSQL_RES對象就是將這些數據進行整合一下。 我們可以把MYSQL_RES對象看成一個數組的指針, 這個數組里面存儲的數據類型是char**類型。 數組的大小表示一共有多少條記錄。 

然后這些元素都指向一個char*的數組:

這個char*元素指向的就是我們的表結構里面的屬性元素。 所以未來我們就可以把MYSQL_RES堪稱一個char** XXX[]數組。

所以, 這個MYSQL_RES其實就是我們使用select語句之后返回的結果, 這個結果的集合就在MYSQL_RES對象中。 未來我們想要去除其中的對象, 我們需要先獲取這個結果集里面的行, 里面的列:

MYSQL_RES *
mysql_store_result(MYSQL *mysql); //獲得結果集
uint64_t
mysql_num_rows(MYSQL_RES *result); //獲取行
unsigned int
mysql_num_fields(MYSQL_RES *result); //獲取列

為了更好的遍歷, mysql提供了一種數據結構MYSQL_ROW, 方便我們更好的遍歷, 以后我們就可以直接把這個RES結果集當成一個二維數組來使用。這個MYSQL_ROW就相當于迭代器, 我們每次調用, 它都可以自動加。

MYSQL_ROW
mysql_fetch_row(MYSQL_RES *result);

然后我們不僅有數據, 還有我們的列名(列屬性)所以我們就可以獲取一下列名:

MYSQL_FIELD *
mysql_fetch_fields(MYSQL_RES *result)

這個函數的返回值是一個結構里, 這個結構體里面有著列名稱、取別名后的原生列名稱、 屬于哪個表、屬于哪個數據庫等等:

未來我們想要的就是這個name字段。 我們然后就可以向遍歷數組一樣遍歷這個列屬性,打印出來列屬性。

所以, 下面為全部的代碼:

#include<iostream>
#include<mysql/mysql.h>  
#include<string>
using namespace std;
const string host = "localhost";
const string user = "mian_yang";    
const string passwd = "MYhylk563_al36huz.6";
const string db = "school_book_manage";
const unsigned int port = 3306;



int main()
{
    MYSQL* my = mysql_init(nullptr);
    if (nullptr)
    {
        cerr << "init MySQL error" << endl;
        return 1;
    }
    //

    if (mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        cerr << "connect error" << endl;
        return 0;
    }
    //
    cout << "connect success" << endl;

    string sql = "select * from user";
    int n = mysql_query(my, sql.c_str());
    if (n == 0) cout << sql << " success" << endl;
    else 
    {
        cerr << sql << " error" << endl;
        return 3;
    }
    //
    MYSQL_RES* res = mysql_store_result(my);
    if (res == nullptr) 
    {
        cerr << "res error" << endl;
        return 4;
    }
    MYSQL_FIELD* fields = mysql_fetch_fields(res);
    my_ulonglong cols = mysql_num_rows(res);
    for (int i = 0; i < cols; i++)
    {
        cout << fields[i].name << "\t";
    }
    cout << endl;   

    my_ulonglong rows = mysql_num_rows(res);
    for (int i = 0; i < rows; i++)
    {
        MYSQL_ROW row = mysql_fetch_row(res);
        for (int j = 0; j < cols; j++)
        {
            cout << row[j] << "\t";
        }
        cout << endl;
    }

    mysql_close(my);
    return 0;
}

 然后打印就打印出來了:

 對于MYSQL_RES, 其實MYSQL_RES就是在內存中申請了一大塊內存空間, 所以最后我們還要free這塊空間。而上層用戶如果使用free釋放空間就會造成內存泄漏或者使用內部的原生指針太麻煩。 所以就提供了一個接口:

void
mysql_free_result(MYSQL_RES *result)

這個函數就是系統(tǒng)提供的釋放我們的結果集。 

到此這篇關于MySQL中C接口的實現的文章就介紹到這了,更多相關MySQL C接口內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySQL中MIN()函數的使用教程

    MySQL中MIN()函數的使用教程

    這篇文章主要介紹了MySQL中MIN()函數的使用教程,是MySQL入門學習中的基礎知識,需要的朋友可以參考下
    2015-05-05
  • MySQL窗口函數實現榜單排名

    MySQL窗口函數實現榜單排名

    相信大家在日常的開發(fā)中經常會碰到榜單類的活動需求,本文主要介紹了MySQL窗口函數實現榜單排名,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • MySQL操作符(and、or、in、not)的具體使用

    MySQL操作符(and、or、in、not)的具體使用

    本文主要介紹了MySQL操作符(and、or、in、not)的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • mysql中異常錯誤ERROR:2002的解決方法

    mysql中異常錯誤ERROR:2002的解決方法

    最近在啟動mysql的時候發(fā)現mysql報錯了,錯誤代碼是2002,通過查找相關的資料發(fā)現是var/lib/mysql 的訪問權限問題,所以這篇文章主要介紹了mysql中異常錯誤ERROR:2002的解決方法,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-03-03
  • MySQL實現免密登錄的三種配置方式

    MySQL實現免密登錄的三種配置方式

    我們登錄MySQL的時候有時候會忘記root密碼,這時我們需要免密登錄,所以這篇文章給大家介紹了MySQL免密登錄的三種方式,文章通過是示例代碼給出了詳細的配置方案,需要的朋友可以參考下
    2024-03-03
  • 詳解MySQL中Order By排序和filesort排序的原理及實現

    詳解MySQL中Order By排序和filesort排序的原理及實現

    這篇文章主要為大家詳細介紹了MySQL的Order By排序的底層原理與filesort排序,以及排序優(yōu)化手段,文中的示例代碼講解詳細,感興趣的小編可以跟隨小編一起學習一下
    2022-08-08
  • MySQL DBA教程:Mysql性能優(yōu)化之緩存參數優(yōu)化

    MySQL DBA教程:Mysql性能優(yōu)化之緩存參數優(yōu)化

    在平時被問及最多的問題就是關于 MySQL 數據庫性能優(yōu)化方面的問題,所以最近打算寫一個MySQL數據庫性能優(yōu)化方面的系列文章,希望對初中級 MySQL DBA 以及其他對 MySQL 性能優(yōu)化感興趣的朋友們有所幫助
    2014-03-03
  • MySQL8.0新特性之不可見主鍵的使用

    MySQL8.0新特性之不可見主鍵的使用

    MySQL8.0.30版本引入不可見主鍵,它可以自動為沒有顯式指定主鍵的?InnoDB?表創(chuàng)建一個不可見的主鍵,本文主要介紹了MySQL8.0新特性之不可見主鍵的使用,具有一定的參考價值,感興趣的可以了解一下
    2024-04-04
  • SQL觸發(fā)器定義與使用

    SQL觸發(fā)器定義與使用

    SQL的觸發(fā)器和存儲過程一樣,都是嵌入到SQL中的一段程序,是SQL中管理數據的有力工具,本文給大家詳細介紹SQL觸發(fā)器的定義語法知識,感興趣的朋友一起看看吧
    2023-01-01
  • MySQL存儲過程中使用動態(tài)行轉列

    MySQL存儲過程中使用動態(tài)行轉列

    這篇文章主要為大家介紹了MySQL存儲過程中使用動態(tài)行轉列的相關資料,需要的朋友可以參考下
    2016-01-01

最新評論