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

C/C++代碼操作MySQL數(shù)據(jù)庫詳細(xì)步驟

 更新時(shí)間:2023年12月05日 16:20:22   作者:慕雪華年  
這篇文章主要給大家介紹了關(guān)于C/C++代碼操作MySQL數(shù)據(jù)庫的相關(guān)資料,通過文中的這些示例,我們可以連接到MySQL數(shù)據(jù)庫,并執(zhí)行常見的數(shù)據(jù)庫操作,如創(chuàng)建表、插入數(shù)據(jù)和查詢數(shù)據(jù),需要的朋友可以參考下

簡(jiǎn)單嘗試使用c語言的庫對(duì)mysql的數(shù)據(jù)進(jìn)行增刪改查

1.新增數(shù)據(jù)庫和表

剛開始數(shù)據(jù)庫沒有設(shè)定密碼和用戶,直接用root用戶登錄

mysql -uroot;

創(chuàng)建一個(gè)hello數(shù)據(jù)庫,并進(jìn)入這個(gè)數(shù)據(jù)庫

create database hello;
use hello;

創(chuàng)建一個(gè)stu_student數(shù)據(jù)表

create table stu_test(
 id int primary key auto_increment,
 name varchar(30),
 age int,
 score decimal(4,2)
);

其中第一個(gè)id的類型是int,并設(shè)置為了auto_increment,每次插入數(shù)據(jù)的時(shí)候它都會(huì)自增。

name是字符串類型,age是int類型,score分?jǐn)?shù)是浮點(diǎn)類型

decimal(4,2)         表示的范圍是 -99.99 ~ 99.99
decimal(4,2)unsigned 表示的范圍是 0 ~ 99.99

到這里,前期的準(zhǔn)備就完成了

2.接口簡(jiǎn)單認(rèn)識(shí)

依照注釋,簡(jiǎn)單認(rèn)識(shí)一下mysql庫的一些接口

//頭文件
#include <mysql/mysql.h>

//Mysql操作句柄初始化
MYSQL *mysql_init(MYSQL *mysql);
//參數(shù)為空則動(dòng)態(tài)申請(qǐng)句柄空間進(jìn)行初始化
//失敗返回NULL

//連接mysql服務(wù)器
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--初始化完成的句柄
//host---連接的mysql服務(wù)器的地址
//user---連接的服務(wù)器的用戶名
//passwd-連接的服務(wù)器的密碼
//db ----默認(rèn)選擇的數(shù)據(jù)庫名稱
//port---連接的服務(wù)器的端口: 默認(rèn)0是3306端口
//unix_socket---通信管道文件或者socket文件,通常置NULL 
//client_flag---客戶端標(biāo)志位,通常置0 
//返回值:成功返回句柄,失敗返回NULL

//設(shè)置當(dāng)前客戶端的字符集
int mysql_set_character_set(MYSQL *mysql, const char *csname) 
//mysql--初始化完成的句柄
//csname--字符集名稱,通常:"utf8" 
//返回值:成功返回0, 失敗返回非0
    
//選擇操作的數(shù)據(jù)庫
int mysql_select_db(MYSQL *mysql, const char *db) 
//mysql--初始化完成的句柄
//db-----要切換選擇的數(shù)據(jù)庫名稱
//返回值:成功返回0, 失敗返回非0
    
//執(zhí)行sql語句
int mysql_query(MYSQL *mysql, const char *stmt_str) 
//mysql--初始化完成的句柄
//stmt_str--要執(zhí)行的sql語句
//返回值:成功返回0, 失敗返回非0
    
//保存查詢結(jié)果到本地
MYSQL_RES *mysql_store_result(MYSQL *mysql) 
//mysql--初始化完成的句柄
//返回值:成功返回結(jié)果集的指針, 失敗返回NULL
    
//獲取結(jié)果集中的行數(shù)與列數(shù)
uint64_t mysql_num_rows(MYSQL_RES *result);
//result--保存到本地的結(jié)果集地址
//返回值:結(jié)果集中數(shù)據(jù)的條數(shù);
unsigned int mysql_num_fields(MYSQL_RES *result) 
//result--保存到本地的結(jié)果集地址
//返回值:結(jié)果集中每一條數(shù)據(jù)的列數(shù);
    
//遍歷結(jié)果集
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) 
//result--保存到本地的結(jié)果集地址
//返回值:實(shí)際上是一個(gè)char **的指針,將每一條數(shù)據(jù)做成了字符串指針數(shù)組 row[0]-第0列 row[1]-第1列
//并且這個(gè)接口會(huì)保存當(dāng)前讀取結(jié)果位置,每次獲取的都是下一條數(shù)據(jù)


//釋放結(jié)果集
void mysql_free_result(MYSQL_RES *result) 
//result--保存到本地的結(jié)果集地址
//返回值:void 
 
//關(guān)閉數(shù)據(jù)庫客戶端連接,銷毀句柄:
void mysql_close(MYSQL *mysql) 
 
//獲取mysql接口執(zhí)行錯(cuò)誤原因
const char *mysql_error(MYSQL *mysql)

因?yàn)閙ysql是一個(gè)動(dòng)態(tài)庫,所以編譯的時(shí)候,需要加上庫名的鏈接

g++ test.cpp -o test -lmysqlclient

在我的系統(tǒng)下,MySQL的庫是在/usr/lib64目錄下的,所以我不需要額外指定庫的路徑。如果你的系統(tǒng)該目錄下沒有libmysqlclient.so ,則需要找到庫安裝的路徑,使用-L命令指定該路徑

g++ test.cpp -o test -L/path/to/mysql/lib -lmysqlclient

3.代碼

開始寫代碼,一步一步認(rèn)識(shí)mysql的各個(gè)接口

3.1 連接數(shù)據(jù)庫

因?yàn)槲业臄?shù)據(jù)庫都是默認(rèn)的環(huán)境,所以不需要賬戶的密碼,按如下宏定義一下我們需要操作的數(shù)據(jù)庫信息,方便后續(xù)的修改

#include <mysql/mysql.h>
#define HOST "127.0.0.1"
#define PORT 3306
#define USER "root"
#define PASSWD ""
#define DBNAME "hello"

第一步,是用init來初始化一個(gè)MYSQL的結(jié)構(gòu)體,并用一個(gè)指針來接收;

第二步,用mysql_real_connect函數(shù)來進(jìn)行數(shù)據(jù)庫的連接,填入我們剛剛的宏定義即可。

第三步,因?yàn)樵谧畛跖渲?code>mariadb的環(huán)境時(shí),為了更好的支持中文,我們將數(shù)據(jù)庫的字符集設(shè)置為了utf8,代碼中也需要同步修改,避免因?yàn)榫幋a問題產(chǎn)生的數(shù)據(jù)亂碼

最后一步,銷毀mysql結(jié)構(gòu)體

int main()
{
    // 連接數(shù)據(jù)庫
    // 初始化
    MYSQL *mysql = mysql_init(nullptr);
    if (mysql == nullptr) // 返回值為空代表init失敗
    { 
        cerr << "[ERR] init mysql handle failed!\n"; 
        return -1; 
    }
    // 連接
    cout << "[INFO] connect to " << HOST << ":" << PORT << " " << USER << " " << DBNAME << endl;
    // 第一個(gè)參數(shù)為輸出型參數(shù)。返回值為MYSQL的起始地址,如果錯(cuò)誤返回NULL
    if (mysql_real_connect(mysql, HOST, USER, PASSWD, DBNAME, PORT, nullptr, 0) == nullptr) 
    {
        cerr << "[ERR] mysql connect error: " << mysql_error(mysql) << endl; 
        return -1;
    }
    // 配置為和數(shù)據(jù)庫同步的utf8字符集
    mysql_set_character_set(mysql, "utf8");
    // 到這里就已經(jīng)成功了
    cout << "[INFO] mysql database connect success!" << endl; 
    
    // 關(guān)閉連接
    mysql_close(mysql); 
    return 0;
}

編譯執(zhí)行,成功鏈接上了數(shù)據(jù)庫

$ make
g++ test.cpp -o test -lmysqlclient
$ ./test
[INFO] connect to 127.0.0.1:3306 root hello
[INFO] mysql database connect success!

3.2 增加鍵值

下面要做的,就是給已有表新增一個(gè)鍵值

需要注意的是,mysql的代碼操作,實(shí)際上也是需要使用sql語句的(這點(diǎn)我覺得好麻煩)

插入語句如下,括號(hào)中的鍵值應(yīng)該和數(shù)據(jù)庫中表的鍵值一一對(duì)應(yīng)

insert into stu_test value (null,'牛爺爺',50,64.6);

所以我們要做的,就是寫一個(gè)函數(shù),將傳入的參數(shù)合并成一個(gè)sql語句,傳入mysql進(jìn)行處理

// 將double轉(zhuǎn)為string
std::string double2string(const double& d)
{
    std::stringstream s_tmp;
    s_tmp << d;  
    std::string s = s_tmp.str();
    return s;
}

int add_key_to_stu(MYSQL *mysql,const std::string& name,int age,double score)
{
    // 1.將傳入的參數(shù)處理為一個(gè)完整的sql語句
    // 因?yàn)榈谝粋€(gè)編號(hào)參數(shù),配置的是自增,所以需要傳入null
    std::string sql_cmd = "insert into stu_test value (null,'";
    sql_cmd+= name;
    sql_cmd+= "',";
    sql_cmd+= std::to_string(age);
    sql_cmd+= ",";
    sql_cmd+= double2string(score);
    sql_cmd+= ");";
    cout << "[INFO] " << sql_cmd << endl;
    
    // 2.執(zhí)行語句
    int ret = mysql_query(mysql,sql_cmd.c_str());
    if(ret!=0)
    {
        cerr << "[ERR] mysql insert error: " << mysql_error(mysql) << endl; 
    }
    return ret;
}

如下代碼測(cè)試

    // 添加一個(gè)數(shù)據(jù)
    add_key_to_stu(mysql,"牛爺爺",50,64.6);
    add_key_to_stu(mysql,"小圖圖",5,72.8);

可以看到,成功運(yùn)行!

$ ./test
[INFO] connect to 127.0.0.1:3306 root hello
[INFO] mysql database connect success!
[INFO] insert into stu_test value (null,'牛爺爺',50,64.6);
[INFO] insert into stu_test value (null,'小圖圖',5,72.8);

進(jìn)入mysql命令行,使用如下命令,即可查詢到已有的鍵值

select * from stu_test;

可以看到,處理成功!

+----+-----------+------+-------+
| id | name      | age  | score |
+----+-----------+------+-------+
|  1 | 牛爺爺    |   50 | 64.60 |
|  2 | 小圖圖    |    5 | 72.80 |
+----+-----------+------+-------+
2 rows in set (0.001 sec)

3.3 修改已有鍵值

sql語句如下,修改當(dāng)前數(shù)據(jù)庫中,stu_test表中name為牛爺爺的條目的成績(jī)?yōu)?0

update stu_test set score=70 where name='牛爺爺';
// 修改已有學(xué)生的成績(jī)
int mod_score_in_stu(MYSQL *mysql,const std::string& name,double score)
{
    std::string sql_cmd = "update ";
    sql_cmd += TABLENAME;
    sql_cmd += " set score=";
    sql_cmd += double2string(score);
    sql_cmd += " where name='";
    sql_cmd += name;
    sql_cmd += "';";
    cout << "[INFO] " << sql_cmd << endl;
    
    // 2.執(zhí)行語句
    int ret = mysql_query(mysql,sql_cmd.c_str());
    if(ret!=0)
    {
        cerr << "[ERR] mysql mod_score error: " << mysql_error(mysql) << endl; 
    }
    return ret;
}

可以看到,執(zhí)行成功了之后,牛爺爺?shù)某煽?jī)發(fā)生了變化

$ ./test
[INFO] connect to 127.0.0.1:3306 root hello
[INFO] mysql database connect success!
[INFO] update stu_test set score=70 where name='牛爺爺';
MariaDB [hello]> select * from stu_test;
+----+-----------+------+-------+
| id | name      | age  | score |
+----+-----------+------+-------+
|  1 | 牛爺爺    |   50 | 64.60 |
|  2 | 小圖圖    |    5 | 72.80 |
+----+-----------+------+-------+
2 rows in set (0.001 sec)

MariaDB [hello]> select * from stu_test;
+----+-----------+------+-------+
| id | name      | age  | score |
+----+-----------+------+-------+
|  1 | 牛爺爺    |   50 | 70.00 |
|  2 | 小圖圖    |    5 | 72.80 |
+----+-----------+------+-------+
2 rows in set (0.000 sec)

如果想修改其他鍵值,也是依照此步驟進(jìn)行。

在實(shí)際場(chǎng)景中,一個(gè)數(shù)據(jù)條目肯定會(huì)有一個(gè)鍵值是不變的。比如在我的學(xué)生表中,假定每一個(gè)學(xué)生的名字都不變,我們就可以根據(jù)name字段來查找鍵值,對(duì)之進(jìn)行其他值的修改。

如果真要嚴(yán)肅起來,用名字來查找肯定是不行的,我們應(yīng)該給每一個(gè)學(xué)生都生成一個(gè)學(xué)號(hào)或UID,用這個(gè)id來進(jìn)行檢索。修改數(shù)據(jù)之前,都需要知道目標(biāo)數(shù)據(jù)的uid值,才能修改。

3.4 刪除鍵值

如下語句,在test_tb表中,刪除名字為張三的鍵值

delete from test_tb where name='張三';

在刪除之前,我又給數(shù)據(jù)庫新增了一個(gè)鍵值

MariaDB [hello]> select * from stu_test;
+----+-----------+------+-------+
| id | name      | age  | score |
+----+-----------+------+-------+
|  1 | 牛爺爺    |   50 | 70.00 |
|  2 | 小圖圖    |    5 | 72.80 |
|  3 | 大司馬    |   42 | 87.30 |
+----+-----------+------+-------+
3 rows in set (0.001 sec)

下面我要用代碼,刪除掉牛爺爺

// 刪除鍵值(根據(jù)名字)
int del_key_in_stu(MYSQL *mysql,const std::string& name)
{
    std::string sql_cmd = "delete from ";
    sql_cmd += TABLENAME;
    sql_cmd += " where name='";
    sql_cmd += name;
    sql_cmd += "';";
    cout << "[INFO] " << sql_cmd << endl;
    
    // 執(zhí)行語句
    int ret = mysql_query(mysql,sql_cmd.c_str());
    if(ret!=0)
    {
        cerr << "[ERR] mysql mod_score error: " << mysql_error(mysql) << endl; 
    }
    return ret;
}
// 刪除已有鍵值
del_key_in_stu(mysql,"牛爺爺");

編譯執(zhí)行

$ ./test
[INFO] connect to 127.0.0.1:3306 root hello
[INFO] mysql database connect success!
[INFO] delete from stu_test where name='牛爺爺';

牛爺爺被刪掉了

MariaDB [hello]> select * from stu_test;
+----+-----------+------+-------+
| id | name      | age  | score |
+----+-----------+------+-------+
|  2 | 小圖圖    |    5 | 72.80 |
|  3 | 大司馬    |   42 | 87.30 |
+----+-----------+------+-------+
2 rows in set (0.000 sec)

3.4.1 關(guān)于自增的id

此時(shí)再插入一個(gè)新的鍵值,可以看到id并么有把空余的1給補(bǔ)上,而是從4開始繼續(xù)往后增加

MariaDB [hello]> select * from stu_test;
+----+-----------+------+-------+
| id | name      | age  | score |
+----+-----------+------+-------+
|  2 | 小圖圖    |    5 | 72.80 |
|  3 | 大司馬    |   42 | 87.30 |
|  4 | 樂迪      |   32 | 99.00 |
+----+-----------+------+-------+
3 rows in set (0.001 sec)

知道這一點(diǎn)就行

3.5 查詢

對(duì)于數(shù)據(jù)庫而言,查詢也是一個(gè)高頻操作

select * from  tb  where name=key;

上面的語句,是在數(shù)據(jù)庫表tb中查找鍵值name為key的的數(shù)據(jù)

// 返回用戶的所有信息,name為空返回所有
void get_all_in_stu(MYSQL *mysql,const std::string& name="")
{
    std::string sql_cmd = "select * from ";
    sql_cmd += TABLENAME;
    if(name.size()!=0)
    {
        sql_cmd += " where name='";
        sql_cmd += name;
        sql_cmd += "'";
    }
    sql_cmd += ";";
    cout << "[INFO] " << sql_cmd << endl;

    int ret = mysql_query(mysql,sql_cmd.c_str());
    if(ret!=0)
    {
        cerr << "[ERR] mysql query error: " << mysql_error(mysql) << endl; 
        return ;
    }
    // 獲取結(jié)果
    MYSQL_RES *res = mysql_store_result(mysql);
    if (res == nullptr) 
    { 
        cerr << "[ERR] mysql store_result error: " << mysql_error(mysql) << endl; 
        return ; 
    }
    
    int row = mysql_num_rows(res); // 行
    int col = mysql_num_fields(res); //列
    printf("%10s%10s%10s%10s\n", "ID", "姓名", "年齡", "成績(jī)"); 
    for (int i = 0; i < row; i++) 
    { 
        MYSQL_ROW row_data = mysql_fetch_row(res); 
        for (int i = 0; i < col; i++) 
        {
            printf("%10s", row_data[i]); 
        }
        printf("\n"); 
    } 
    // 釋放結(jié)果
    mysql_free_result(res);
}
get_all_in_stu(mysql);

執(zhí)行結(jié)果如下,顯示出了表中所有的值

[INFO] connect to 127.0.0.1:3306 root hello
[INFO] mysql database connect success!
[INFO] select * from stu_test;
        ID    姓名    年齡    成績(jī)
         2 小圖圖         5     72.80
         3 大司馬        42     87.30
         4    樂迪        32     99.00

傳入特定名字,則只返回改名字所有值

get_all_in_stu(mysql,"樂迪");
[INFO] select * from stu_test where name='樂迪';
        ID    姓名    年齡    成績(jī)
         4    樂迪        32     99.00

這樣便實(shí)現(xiàn)了查詢操作。

3.5.1 模糊匹配

除了使用name=,還可以使用name like %名字%這條語句進(jìn)行模糊匹配,即不在乎名字前后的內(nèi)容,只要有包含名字的數(shù)據(jù),就篩選出來。

select * from %s where name like '%牛%';

這樣就能將名字里面包含牛的所有數(shù)據(jù)都篩選出來

3.5.2 查詢接口操作注意事項(xiàng)

因?yàn)椴樵兊姆祷刂凳且粋€(gè)字符串二維數(shù)組,并不能通過字段名字獲取到對(duì)應(yīng)字段的內(nèi)容。這要求程序猿知曉這個(gè)表中字段的順序,才能通過下標(biāo)獲取到正確的字段對(duì)其進(jìn)行處理。

因?yàn)閏pp并不像python那樣支持可變變量類型,所以要想篩選出對(duì)應(yīng)類型的數(shù)據(jù),還需要我們自行調(diào)用對(duì)應(yīng)的函數(shù)進(jìn)行數(shù)據(jù)的轉(zhuǎn)換。

比如用atoi函數(shù)將字符串轉(zhuǎn)為整型。

總結(jié)

到此這篇關(guān)于C/C++代碼操作MySQL數(shù)據(jù)庫詳細(xì)步驟的文章就介紹到這了,更多相關(guān)C/C++操作數(shù)據(jù)庫內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++按位異或運(yùn)算符的使用介紹

    C++按位異或運(yùn)算符的使用介紹

    本篇文章對(duì)C++按位異或運(yùn)算符的使用進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • Pipes實(shí)現(xiàn)LeetCode(193.驗(yàn)證電話號(hào)碼)

    Pipes實(shí)現(xiàn)LeetCode(193.驗(yàn)證電話號(hào)碼)

    這篇文章主要介紹了Pipes實(shí)現(xiàn)LeetCode(193.驗(yàn)證電話號(hào)碼),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C++實(shí)現(xiàn)raw_input的方法

    C++實(shí)現(xiàn)raw_input的方法

    這篇文章主要介紹了C++實(shí)現(xiàn)raw_input的方法,通過C++來實(shí)現(xiàn)Python中發(fā)raw_input的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-10-10
  • 詳解C++ 動(dòng)態(tài)內(nèi)存分配與命名空間

    詳解C++ 動(dòng)態(tài)內(nèi)存分配與命名空間

    這篇文章主要介紹了詳解C++ 動(dòng)態(tài)內(nèi)存分配與命名空間,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • C++實(shí)現(xiàn)二叉樹及堆的示例代碼

    C++實(shí)現(xiàn)二叉樹及堆的示例代碼

    這篇文章主要介紹了C++實(shí)現(xiàn)二叉樹及堆的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • C程序結(jié)構(gòu)的入門

    C程序結(jié)構(gòu)的入門

    在我們學(xué)習(xí) C 語言的基本構(gòu)建塊之前,讓我們先來看看一個(gè)最小的 C 程序結(jié)構(gòu),在接下來的章節(jié)中可以以此作為參考
    2021-06-06
  • 解析C++編程中的bad_cast異常

    解析C++編程中的bad_cast異常

    這篇文章主要介紹了C++編程中的bad_cast異常,bad_cast異常通常出現(xiàn)于表達(dá)式中類型轉(zhuǎn)換錯(cuò)誤時(shí)等一些場(chǎng)景,需要的朋友可以參考下
    2016-01-01
  • 基于C語言編寫一個(gè)簡(jiǎn)單的抽卡小游戲

    基于C語言編寫一個(gè)簡(jiǎn)單的抽卡小游戲

    這篇文章主要為大家介紹了如何利用C語言實(shí)現(xiàn)原神抽卡的小游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-04-04
  • c++中ref的作用示例解析

    c++中ref的作用示例解析

    這篇文章主要為大家介紹了c++中ref的作用示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Qt實(shí)現(xiàn)獲取文件大小與磁盤空間大小

    Qt實(shí)現(xiàn)獲取文件大小與磁盤空間大小

    這篇文章主要為大家詳細(xì)介紹了如何使用Qt實(shí)現(xiàn)獲取文件大小與磁盤空間大小,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11

最新評(píng)論