C++連接mysql數(shù)據(jù)庫(改進(jìn)版)
使用vs2019對(duì)window11中的數(shù)據(jù)庫進(jìn)行連接
1. 配置連接環(huán)境
首先需要把mysql中的頭文件和庫文件放入到c++項(xiàng)目工程中
1.打開安裝MySQL的目錄,在windows系統(tǒng)中如果是默認(rèn)路徑,應(yīng)該和我的是一樣的:C:\Program Files\MySQL\MySQL Server 8.0
2.找到include,和lib文件,include文件是包含的頭文件,lib文件是包含的庫文件
3.在創(chuàng)建的c++工程中加入include,lib文件路徑,按一下步驟
1.工程中的項(xiàng)目找到屬性
2.到 VC++ 目錄 中的包含目錄和庫目錄分別加入include文件和lib文件的路徑,
這是我的路徑:include文件路徑:C:\Program Files\MySQL\MySQL Server 8.0\include
lib文件路徑:C:\Program Files\MySQL\MySQL Server 8.0\lib
3. 到 鏈接器 中的 輸入 中的 附加依賴項(xiàng)中 加入 libmysql.lib 的依賴:
4.還需要把下圖中的 libmysql.dll 的文件復(fù)制到 C:\Windows\System32 目錄中
連接mysql可以參考 mysql參考手冊(cè) 進(jìn)行查看
2.代碼實(shí)現(xiàn)連接
例子:
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<mysql.h>#include<time.h>#include<stdlib.h>intmain(){ int sr; srand((unsigned)time(NULL)); sr = rand() % 50 + 1; //固定不變的 MYSQL mysql; //一個(gè)數(shù)據(jù)庫結(jié)構(gòu)體 MYSQL_RES* res; //一個(gè)結(jié)果集結(jié)構(gòu)體 MYSQL_ROW row; //char** 二維數(shù)據(jù),存放一條條記錄 //初始化數(shù)據(jù)庫 mysql_init(&mysql); //設(shè)置編碼方式 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); //連接數(shù)據(jù)庫 //ip地址 //用戶名 //密碼 //數(shù)據(jù)庫名 if (mysql_real_connect(&mysql, "localhost", "root", "Z20020803", "box_man", 3306, NULL, 0) == NULL) { printf("錯(cuò)誤原因:%s\n", mysql_error(&mysql)); printf("連接失敗\n"); exit(-1); } //往數(shù)據(jù)庫中插入一個(gè)隨機(jī)數(shù) char* str1 = "insert into rand values("; char sql_insert[200]; sprintf(sql_insert, "%s%d%s", str1, sr, ")"); mysql_query(&mysql, sql_insert); //sql語句提交 //查詢數(shù)據(jù) mysql_query(&mysql, "select * from rand"); //獲取結(jié)果集 res = mysql_store_result(&mysql); //給ROW賦值,判斷ROW是否為空,不為空就打印數(shù)據(jù) while (row = mysql_fetch_row(res)) { printf("%s\n", row[0]); } //釋放結(jié)果集 mysql_free_result(res); //關(guān)閉數(shù)據(jù)庫 mysql_close(&mysql); //停留等待 system("pause"); return0; }
使用c++語句對(duì)數(shù)據(jù)庫進(jìn)行增刪改查,在使用c++中string類型時(shí),需要把string類型轉(zhuǎn)換為c中的類型,使用mysql_query函數(shù)把sql語句提交,查詢成功返回0,結(jié)果會(huì)被保存到mysql對(duì)象中,查詢失敗會(huì)返回非0值:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<mysql.h> #include<string> usingnamespace std; intmain(){ MYSQL mysql; MYSQL_RES* res; MYSQL_ROW row; mysql_init(&mysql); if (mysql_real_connect(&mysql, "localhost", "root", "Z20020803", "box_man", 3306, NULL, 0) == NULL) { printf("錯(cuò)誤提示:%s\n", mysql_error(&mysql)); printf("連接失敗\n"); } //設(shè)置字符集 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); string str1 = "alter table tb_77 modify sex varchar(20)";//修改表類型失敗 mysql_query(&mysql, str1.c_str()); string str = "insert into tb_77 values(5,'sdmqy','h')";//增加數(shù)據(jù)成功,不可以增加漢字 mysql_query(&mysql, str.c_str()); printf("%s", str.c_str()); string str2 = "delete from tb_77 where sex = '女';";//刪除數(shù)據(jù)成功 mysql_query(&mysql, str2.c_str()); string str3 = "update tb_77 set name = 'ttb' where id = 2";//更改也行 mysql_query(&mysql, str3.c_str()); mysql_close(&mysql); return0; }
3.各個(gè)類說明:
1. mysql句柄類(是一個(gè)結(jié)構(gòu)體)
MYSQL mysql;
該類在c++中操作數(shù)據(jù)庫都要使用到
結(jié)構(gòu)體原型:
typedef struct MYSQL { NET net; /* Communication parameters */ unsigned char *connector_fd; /* ConnectorFd for SSL */ char *host, *user, *passwd, *unix_socket, *server_version, *host_info; char *info, *db; struct CHARSET_INFO *charset; MYSQL_FIELD *fields; struct MEM_ROOT *field_alloc; uint64_t affected_rows; uint64_t insert_id; /* id if insert on table with NEXTNR */ uint64_t extra_info; /* Not used */ unsigned long thread_id; /* Id for connection in server */ unsigned long packet_length; unsigned int port; unsigned long client_flag, server_capabilities; unsigned int protocol_version; unsigned int field_count; unsigned int server_status; unsigned int server_language; unsigned int warning_count; struct st_mysql_options options; enum mysql_status status; enum enum_resultset_metadata resultset_metadata; bool free_me; /* If free in mysql_close */ bool reconnect; /* set to 1 if automatic reconnect */ /* session-wide random string */ char scramble[SCRAMBLE_LENGTH + 1]; LIST *stmts; /* list of all statements */ const struct MYSQL_METHODS *methods; void *thd; /* Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag from mysql_stmt_close if close had to cancel result set of this object. */ bool *unbuffered_fetch_owner; void *extension; } MYSQL;
2.MYSQL_RES查詢結(jié)果集(是一個(gè)結(jié)構(gòu)體)
MYSQL_RES * res=nullptr;
用來保存查詢到的所有結(jié)果
結(jié)構(gòu)體原型:
typedef struct MYSQL_RES { uint64_t row_count; MYSQL_FIELD *fields; struct MYSQL_DATA *data; MYSQL_ROWS *data_cursor; unsigned long *lengths; /* column lengths of current row */ MYSQL *handle; /* for unbuffered reads */ const struct MYSQL_METHODS *methods; MYSQL_ROW row; /* If unbuffered read */ MYSQL_ROW current_row; /* buffer to current row */ struct MEM_ROOT *field_alloc; unsigned int field_count, current_field; bool eof; /* Used by mysql_fetch_row */ /* mysql_stmt_close() had to cancel this result */ bool unbuffered_fetch_cancelled; enum enum_resultset_metadata metadata; void *extension; } MYSQL_RES;
3.MYSQL_ROW獲取結(jié)果集中的內(nèi)容:本質(zhì)上是一個(gè)char類型的二級(jí)指針
MYSQL_ROW row
該變量可以獲取到結(jié)果集中的數(shù)據(jù)
4.MYSQL_FIELD獲取結(jié)果集中表的所有內(nèi)容(是一個(gè)結(jié)構(gòu)體)
結(jié)構(gòu)體原型:
typedef struct MYSQL_FIELD { char *name; /* Name of column */ char *org_name; /* Original column name, if an alias */ char *table; /* Table of column if column was a field */ char *org_table; /* Org table name, if table was an alias */ char *db; /* Database for table */ char *catalog; /* Catalog for table */ char *def; /* Default value (set by mysql_list_fields) */ unsigned long length; /* Width of column (create length) */ unsigned long max_length; /* Max width for selected set */ unsigned int name_length; unsigned int org_name_length; unsigned int table_length; unsigned int org_table_length; unsigned int db_length; unsigned int catalog_length; unsigned int def_length; unsigned int flags; /* Div flags */ unsigned int decimals; /* Number of decimals in field */ unsigned int charsetnr; /* Character set */ enum enum_field_types type; /* Type of field. See mysql_com.h for types */ void *extension; } MYSQL_FIELD;
4.一些函數(shù)說明
mysql的使用手冊(cè)網(wǎng)址:MySQL :: MySQL 8.0 C API 開發(fā)人員指南 :: 5.4.23 mysql_field_count()
部分API函數(shù)
函數(shù) | 作用 |
mysql_init() | 獲取或初始化MYSQL結(jié)構(gòu)。 |
mysql_real_connect() | 連接到MySQL服務(wù)器。 |
mysql_query() | 執(zhí)行指定為“以Null終結(jié)的字符串”的SQL查詢。 |
mysql_store_result() | 檢索完整的結(jié)果集至客戶端。 |
mysql_use_result() | 初始化逐行的結(jié)果集檢索 |
mysql_fetch_field() | 返回下一個(gè)表字段的類型。 |
mysql_fetch_fields() | 返回所有字段結(jié)構(gòu)的數(shù)組。 |
mysql_fetch_lengths() | 返回當(dāng)前行中所有列的長(zhǎng)度。 |
mysql_fetch_row() | 從結(jié)果集中獲取下一行 |
mysql_field_count() | 返回上次執(zhí)行語句的結(jié)果列的數(shù)目。 |
mysql_free_result() | 釋放結(jié)果集使用的內(nèi)存。 |
mysql_close() | 關(guān)閉服務(wù)器連接。 |
mysql_autocommit() | 切換 autocommit模式,ON/OFF |
mysql_commit() | 提交事務(wù)。 |
mysql_errno() | 返回上次調(diào)用的MySQL函數(shù)的錯(cuò)誤編號(hào) |
mysql_options() | 為mysql_connect()設(shè)置連接選項(xiàng) |
mysql_ping() | 檢查與服務(wù)器的連接是否工作,如有必要重新連接。 |
在下列函數(shù)中,從連接數(shù)據(jù)庫到獲取數(shù)據(jù)庫中的數(shù)據(jù)主要使用到1-7的函數(shù)。
1.mysql_init函數(shù):初始化MYSQL變量
函數(shù)原型:
MYSQL *mysql_init(MYSQL *mysql)
說明:
1.如果mysql是NULL指針,該函數(shù)將分配、初始化、并返回新對(duì)象。
2.否則,將初始化對(duì)象,并返回對(duì)象的地址。
3.如果mysql_init()分配了新的對(duì)象,應(yīng)當(dāng)在程序中調(diào)用mysql_close() 來關(guān)閉連接,以釋放對(duì)象
參數(shù)解釋:
返回值:初始化的MYSQL*句柄。如果無足夠內(nèi)存以分配新的對(duì)象,返回NULL。
錯(cuò)誤,在內(nèi)存不足的情況下,返回NULL
2.mysql_read_connect函數(shù):使用該函數(shù)連接mysql數(shù)據(jù)庫
函數(shù)原型:
mysql_real_connect( MYSQL *mysql, ///< 數(shù)據(jù)庫句柄 constchar *host, ///< 主機(jī)名 constchar *user, ///< 用戶名 constchar *passwd,///< 密碼 constchar *db, ///< 數(shù)據(jù)庫名 unsignedint port, ///< 端口號(hào)(MySQL為3306) constchar *unix_socket,///< unix_socket–unix連接方式,為NULL時(shí)表示不使用socket或管道機(jī)制 unsignedlong clientflag ///< clientflag–Mysql運(yùn)行為ODBC數(shù)據(jù)庫的標(biāo)記,一般取0,該參數(shù)可以設(shè)置提交的sql語句為多條語句 ); 作用:連接數(shù)據(jù)庫引擎,通過函數(shù)mysql_real_connect()嘗試與運(yùn)行在主機(jī)上的MySQL數(shù)據(jù)庫引擎建立連接。 返回值:如果連接成功,返回MYSQL*連接句柄。如果連接失敗,返回NULL。對(duì)于成功的連接,返回值與第1個(gè)參數(shù)的值相同。
3.mysql_real_query和mysql_query函數(shù):進(jìn)行數(shù)據(jù)庫查詢(也就是遞交sql語句)
函數(shù)原型:
int STDCALL mysql_real_query(MYSQL *mysql, const char *query, unsigned long length); 說明:執(zhí)行由“Null終結(jié)的字符串”查詢指向的SQL查詢。 正常情況下,字符串必須包含1條SQL語句,而且不應(yīng)為語句添加終結(jié)分號(hào)(‘;')或“\g”。 如果允許多語句執(zhí)行,字符串可包含多條由分號(hào)隔開的語句。(“多查詢執(zhí)行的C API處理”)mysql_query() 不能用于包含二進(jìn)制數(shù)據(jù)的查詢,應(yīng)使用mysql_real_query()取而代之(二進(jìn)制數(shù)據(jù)可能包含字符‘\0', mysql_query()會(huì)將該字符解釋為查詢字符串結(jié)束)。如果希望了解查詢是否應(yīng)返回結(jié)果集, 可使用mysql_field_count()進(jìn)行檢查。 返回值:如果查詢成功,返回0。如果出現(xiàn)錯(cuò)誤,返回非0值。 int mysql_query(MYSQL *mysql, const char *query) 返回值:如果查詢成功,返回0。如果出現(xiàn)錯(cuò)誤,返回非0值。 參數(shù)解釋: 參數(shù)mysql:前面使用MYSQL結(jié)構(gòu)體定義的變量; 參數(shù)query:sql語句 參數(shù)length:sql語句的長(zhǎng)度
4.mysql_store_result和mysql_use_result函數(shù):獲取查詢結(jié)果數(shù)據(jù)
函數(shù)原型:
MYSQL_RES *mysql_store_result(MYSQL *mysql) 說明: 1.對(duì)于成功檢索了數(shù)據(jù)的每個(gè)查詢(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等) ,必須調(diào)用mysql_store_result()或mysql_use_result() 。 2.如果希望了解查詢是否應(yīng)返回結(jié)果集,可使用mysql_field_count()進(jìn)行檢查。 3.如果查詢未返回結(jié)果集,mysql_store_result()將返回Null指針(例如, 如果查詢是INSERT語句)。 4.如果讀取結(jié)果集失敗,mysql_store_result()還會(huì)返回Null指針。通過檢查mysql_error() 是否返回非空字符串,mysql_errno()是否返回非0值,或mysql_field_count()是否返回0, 可以檢查是否出現(xiàn)了錯(cuò)誤。 5.如果未返回行,將返回空的結(jié)果集。(空結(jié)果集設(shè)置不同于作為返回值的空指針)。 6.一旦調(diào)用了mysql_store_result()并獲得了不是Null指針的結(jié)果,可調(diào)用 mysql_num_rows()來找出結(jié)果集中的行數(shù)。 7.可以調(diào)用mysql_fetch_row()來獲取結(jié)果集中的行,或調(diào)用mysql_row_seek()和 mysql_row_tell()來獲取或設(shè)置結(jié)果集中的當(dāng)前行位置。 8.一旦完成了對(duì)結(jié)果集的操作,必須調(diào)用mysql_free_result()。 返回值:具有多個(gè)結(jié)果的MYSQL_RES結(jié)果集合。如果出現(xiàn)錯(cuò)誤,返回NULL。 MYSQL_RES * mysql_use_result(MYSQL *mysql); 說明:調(diào)用mysql_use_result初始化檢索,以便于后面一行一行的讀取結(jié)果集,而它本身并沒有從 服務(wù)器讀取任何數(shù)據(jù),這種方式較之第一種速度更快且所需內(nèi)存更少,但它會(huì)綁定服務(wù)器,阻止其他線程 更新任何表,而且必須重復(fù)執(zhí)行mysql_fetch_row讀取數(shù)據(jù),直至返回NULL,否則未讀取的行會(huì)在下一 次查詢時(shí)作為結(jié)果的一部分返回,故經(jīng)常我們使用mysql_store_result。
5.mysql_fetch_row函數(shù):讀取結(jié)果集數(shù)據(jù)
函數(shù)原型:
MYSQL_ROW mysql_fetch_row(MYSQL_RES* result) 說明: 1.在mysql_store_result()之后使用時(shí),如果沒有要檢索的行,mysql_fetch_row()返回NULL。 2.在mysql_use_result()之后使用時(shí),如果沒有要檢索的行或出現(xiàn)了錯(cuò)誤, mysql_fetch_row()返回NULL。 3.行內(nèi)值的數(shù)目由mysql_num_fields(result)給出。如果行中保存了調(diào)用 mysql_fetch_row()返回的值,將按照row[0]到row[mysql_num_fields(result)-1], 訪問這些值的指針。 4.可以通過調(diào)用mysql_fetch_lengths()來獲得行中字段值的長(zhǎng)度。對(duì)于空字段以及 包含NULL的字段,長(zhǎng)度為0。通過檢查字段值的指針,能夠區(qū)分它們。如果指針為NULL, 字段為NULL,否則字段為空。 參數(shù):是函數(shù)mysql_store_result或mysql_use_result的返回值 返回值:下一行的MYSQL_ROW結(jié)構(gòu)。如果沒有更多要檢索的行或出現(xiàn)了錯(cuò)誤,返回NULL。
6.mysql_free_result函數(shù):釋放結(jié)果集
函數(shù)原型:
void mysql_free_result(MYSQL_RES *result) 說明:釋放由mysql_store_result()、mysql_use_result()、mysql_list_dbs()等為結(jié)果 集分配的內(nèi)存。完成對(duì)結(jié)果集的操作后,必須調(diào)用mysql_free_result()釋放結(jié)果集使用的內(nèi)存。
7.mysql_close函數(shù):關(guān)閉數(shù)據(jù)庫連接
函數(shù)原型:
void mysql_close(MYSQL *mysql) 說明:關(guān)閉前面打開的連接。如果句柄是由mysql_init()或mysql_connect()自動(dòng)分配的, mysql_close()還將解除分配由mysql指向的連接句柄。
8.mysql_num_fields(MYSQL_RES*):該函數(shù)可以拿表中的列數(shù),返回值是一個(gè)unsigned類型
函數(shù)原型:
unsigned int STDCALL mysql_num_fields(MYSQL_RES *res);
9.mysql_fetch_fields(MYSQL_RES*): 該函數(shù)可以拿到表中每一列的字段名,返回的是一個(gè)結(jié)構(gòu)體數(shù)組
函數(shù)原型:
MYSQL_FIELD *STDCALL mysql_fetch_fields(MYSQL_RES *res);
10.mysql_fetch_lengths(MYSQL_RES*):該函數(shù)拿到行中每一列的字段長(zhǎng)度,返回結(jié)果是一個(gè)unsigned類型
函數(shù)原型:
unsigned long *STDCALL mysql_fetch_lengths(MYSQL_RES *result);
11.mysql_field_count函數(shù):返回最近查詢的列數(shù) 。
函數(shù)原型:
unsigned int mysql_field_count(MYSQL *mysql) 說明:此函數(shù)的正常用法是當(dāng)返回 mysql_store_result() 時(shí)(因此您沒有結(jié)果集) 指針)。 在這種情況下,您可以調(diào)用 mysql_field_count() 來 確定 mysql_store_result() 是否應(yīng) 產(chǎn)生了非空的結(jié)果
5.事務(wù)設(shè)置:
在mysql中事務(wù)是默認(rèn)自動(dòng)提交的,如果需要提交的事務(wù)多,對(duì)我們的操作會(huì)有影響,所以需要設(shè)置事務(wù)為手動(dòng)提交
- mysql_autocommit(MYSQL* , mode) 設(shè)置事務(wù)是否自動(dòng)提交函數(shù)
參數(shù):mode如果為“1”,自動(dòng)提交,為“0”為手動(dòng)提交 返回值:提交成功返回0,否則返回非0
- mysql_commit(MYSQL* mysql) 事務(wù)提交函數(shù)
返回值:成功返回0,否則返回非0
- mysql_rollback(MYSQL* mysql) 事務(wù)回滾函數(shù)
返回值:成功返回0,否則返回非0
6.打印錯(cuò)誤信息:
- const char* mysql_error(MYSQL* mysql):返回錯(cuò)誤信息的描述
- const char* mysql_errno(MYSQL* mysql):返回錯(cuò)誤的編號(hào)
代碼使用的例子
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<mysql.h> usingnamespace std; intmain(){ //創(chuàng)建句柄 MYSQL mysql; //創(chuàng)建數(shù)據(jù)集變量 MYSQL_RES* res = nullptr; //創(chuàng)建結(jié)果集變量 MYSQL_ROW row; //創(chuàng)建一個(gè)結(jié)構(gòu)體 MYSQL_FIELD* field; //初始化數(shù)據(jù)庫句柄 mysql_init(&mysql); //設(shè)置字符集 //mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); mysql_set_character_set(&mysql, "gbk"); //開始連接數(shù)據(jù)庫 if (mysql_real_connect(&mysql, "localhost", "root", "Z20020803", "box_man", 3306, NULL, 0)) { cout << "連接成功" << endl; } else { cout << "連接失敗" << endl; return0; } //設(shè)置事務(wù) mysql_autocommit(&mysql, "1"); //增加數(shù)據(jù) string str1 = "insert into tb_912 values(2, 'xiaoming', '李四');"; char ssql[1024]; //使用sprintf拼出來的語句是一個(gè)標(biāo)準(zhǔn)的c語言字符串,可以使用該函數(shù)插入變量值 sprintf(ssql, "insert into tb_912 values(%d, '%s', '%s');", 3, "daming", "17777777772"); if (mysql_query(&mysql, ssql))//該語句提交成功返回0,失敗返回1 { cout << "提交失敗" << endl; } else { cout << "提交成功" << endl; } //提交語句 mysql_query(&mysql, str1.c_str()); //刪除數(shù)據(jù) string str3 = "delete from tb_912 where id = 2"; mysql_query(&mysql, str3.c_str()); //修改數(shù)據(jù) string str4 = "update tb_912 set name = '張三' where id = 1"; mysql_query(&mysql, str4.c_str()); //查詢數(shù)據(jù) string str2 = "select * from tb_912"; mysql_query(&mysql, str2.c_str()); //事務(wù)提交 mysql_commit(&mysql); //獲取里面的結(jié)果集 res = mysql_store_result(&mysql); //拿到結(jié)果集得列數(shù),調(diào)用的是 mysql_store_result() 的返回值, unsignedint a = mysql_num_fields(res); cout <<"表得列數(shù):"<< a << endl; //使用 mysql_fetch_fields() 函數(shù)獲取列的名字,返回的是一個(gè)結(jié)構(gòu)體數(shù)組 field = mysql_fetch_fields(res); for (unsigned i = 0; i < a; i++) { cout << "當(dāng)前列的名字:" << field[i].name << endl;//取出名字 } unsignedlong* lengths; //從結(jié)果集中獲取到數(shù)據(jù) mysql_fetch_row() 獲取結(jié)果集中的一行數(shù)據(jù), //成功:返回記錄當(dāng)前行中每個(gè)字段的值,失敗:返回一個(gè)null while (row = mysql_fetch_row(res)) { printf("%s %s %s \n", row[0], row[1], row[2]); //獲取列中字段的長(zhǎng)度 lengths = mysql_fetch_lengths(res);//返回的是一個(gè)數(shù)組地址 for (unsignedint i = 0; i < a; i++) { cout << "當(dāng)前列的長(zhǎng)度:" << lengths[i] << endl;//列數(shù)會(huì)構(gòu)成一個(gè)數(shù)組 } } //釋放結(jié)果集 mysql_free_result(res); //關(guān)閉mysql實(shí)例 mysql_close(&mysql); return0; }
多條語句提交的代碼實(shí)現(xiàn)
#include<iostream> #include<mysql.h> #include<thread> #include<sstream> #include<map> using namespace std; int main() { //1.創(chuàng)建句柄 MYSQL mysql; //2.初始化mysql mysql_init(&mysql); const char* host = "127.0.0.1"; const char* user = "root"; const char* pwd = "Z20020803"; const char* db = "database1"; //設(shè)定字符集 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); //3.連接數(shù)據(jù)庫 //一次性執(zhí)行多條語句,mysql_real_connect 函數(shù)的最后一個(gè)參數(shù)設(shè)置 if (!mysql_real_connect(&mysql, host, user, pwd, db, 3306, 0, CLIENT_MULTI_STATEMENTS))//阻塞函數(shù) { cout << "connect fail, " << mysql_error(&mysql) << endl; } else { cout << "mysql connect " << host << "success" << endl; } //1.創(chuàng)建表 string sql = "CREATE TABLE IF NOT EXISTS t_image (\ id int AUTO_INCREMENT,\ name varchar(1024),\ path varchar(1024),\ size int,\ PRIMARY KEY(id)\ );"; //2.刪除數(shù)據(jù) sql += "truncate t_image;"; //3.插入數(shù)據(jù) for (int i = 0; i < 1000; i++) { //sql = "insert t_image (name, path, size) values ('test.jpg', 'd:/img/test.jpg', 1024)"; stringstream ss;//用于拼接字符串 ss << "insert t_image (name, path, size) values ('image"; ss << i << ".jpg', 'd:/image/',1024);"; sql += ss.str(); } //4.修改數(shù)據(jù) sql += "update t_image set name = 'test3.png', size = 100 where id = 3;"; //5.刪除數(shù)據(jù) sql += "delete from t_image where id = 1;"; //6.查詢數(shù)據(jù) sql += "select * form t_image;"; //執(zhí)行sql語句會(huì)立刻返回,但在數(shù)據(jù)庫中是沒有執(zhí)行好的,需要獲取結(jié)果 int re = mysql_query(&mysql, sql.c_str());//只提交一次 if (re == 0) { int count = mysql_affected_rows(&mysql); cout << "mysql_affected_rows " << count << "id = " << mysql_insert_id(&mysql) << endl; } else { cout << "mysql_query failed " << mysql_error(&mysql) << endl; } //多個(gè)返回結(jié)果 do { MYSQL_RES* result = mysql_store_result(&mysql); if (result) { cout << "有select數(shù)據(jù),行數(shù):" << mysql_num_rows(result) << endl; mysql_free_result(result);//釋放結(jié)果集 } else//INSERT UPDATE DELETE CREATE DROP truncate { if (mysql_field_count(&mysql) > 0)//select 是否為空 { cout << "Not retrieve result!" << mysql_error(&mysql) << endl; } else//INSERT UPDATE DELETE CREATE DROP truncate { //等待執(zhí)行結(jié)果集 cout << mysql_affected_rows(&mysql) << " rows affectd" << endl; } } } while (mysql_next_result(&mysql) == 0);//表示還有下一條結(jié)果 mysql_close(&mysql); mysql_library_end(); getchar(); return 0; }
圖片的插入及獲取
#include<iostream> #include<mysql.h> #include<thread> #include<sstream> #include<map> #include<chrono> #include<fstream> using namespace std; using namespace chrono; int main() { //1.創(chuàng)建句柄 MYSQL mysql; //2.初始化mysql mysql_init(&mysql); const char* host = "127.0.0.1"; const char* user = "root"; const char* pwd = "Z20020803"; const char* db = "database1"; //設(shè)定字符集 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); //3.連接數(shù)據(jù)庫 if (!mysql_real_connect(&mysql, host, user, pwd, db, 3306, 0, CLIENT_MULTI_STATEMENTS))//阻塞函數(shù) { cout << "connect fail, " << mysql_error(&mysql) << endl; } else { cout << "mysql connect " << host << "success" << endl; } //1.創(chuàng)建表 使用了二進(jìn)制的blob類型 string sql = "CREATE TABLE IF NOT EXISTS t_data (\ id int AUTO_INCREMENT,\ name varchar(1024),\ data blob,\ size int,\ PRIMARY KEY(id)\ )ENGINE=InnoDB;"; int re = mysql_query(&mysql, sql.c_str()); if (re != 0) { cout << mysql_error(&mysql) << endl; } //2.清空表 sql = "truncate t_data"; re = mysql_query(&mysql, sql.c_str()); if (re != 0) { cout << mysql_error(&mysql) << endl; } //3..創(chuàng)建stmt對(duì)象 MYSQL_STMT* stmt = mysql_stmt_init(&mysql); if (!stmt) { cout << "mysql_stmt_init " << mysql_error(&mysql) << endl; } //4.預(yù)處理sql語句 sql = "INSERT INTO t_data (name, data, size) VALUES(?,?,?)"; if (mysql_stmt_prepare(stmt, sql.c_str(), sql.size())) { cerr << "mysql_stmt_prepare failed" << mysql_stmt_error(stmt) << endl; } //使用c++方式打開文件,也可以使用c語言的方式打開文件 //5.打開文件 string filename = "1.jpg"; //文件大小和文件二進(jìn)制地址 int filesize = 0; //讀取二進(jìn)制 fstream in(filename, ios::in | ios::binary); if (!in.is_open()) { cerr << "file " << filename << " open failed!" << endl; } //文件指針移動(dòng)到結(jié)尾處 in.seekg(0, ios::end); //文件大小和文件二進(jìn)制地址 filesize = in.tellg(); //文件指針回到開頭 in.seekg(0, ios::beg); //讀取數(shù)據(jù) char* data = new char[filesize]; int readed = 0;//已經(jīng)讀了多少 while (!in.eof()) { in.read(data + readed, filesize - readed); //讀取了多少字節(jié) if (in.gcount() <= 0) { break; } readed += in.gcount(); } in.close(); //6.綁定字段 MYSQL_BIND bind[3] = { 0 }; bind[0].buffer_type = MYSQL_TYPE_STRING; //name 文件名 bind[0].buffer = (char*)filename.c_str(); bind[0].buffer_length = filename.size(); bind[1].buffer_type = MYSQL_TYPE_BLOB; bind[1].buffer = data; bind[1].buffer_length = filesize; //文件大小 bind[2].buffer_type = MYSQL_TYPE_LONG; bind[2].buffer = &filesize; //綁定stmt對(duì)象 if (mysql_stmt_bind_param(stmt, bind) != 0) { cerr << "mysql_stmt_bind_param failed" << mysql_stmt_error(stmt) << endl; } //7.執(zhí)行stmt sql if (mysql_stmt_execute(stmt) != 0) { cerr << "mysql_stmt_execute failed" << mysql_stmt_error(stmt) << endl; } delete data; mysql_stmt_close(stmt); //獲取數(shù)據(jù) sql = "select * from t_data"; re = mysql_query(&mysql, sql.c_str()); if (re != 0) { cout << "mysql_store_result failed" << mysql_error(&mysql) << endl; } //獲取結(jié)果集 MYSQL_RES* res = mysql_store_result(&mysql); if (res == NULL) { cerr << "mysql_store_result failed" << mysql_error(&mysql) << endl; } //取一行數(shù)據(jù) MYSQL_ROW row = mysql_fetch_row(res); if (!row) { cerr << "mysql_fetch_row failed" << mysql_error(&mysql) << endl; } cout << row[0] << " " << row[1] << " " << row[2] << endl; //獲取每一列字段的長(zhǎng)度 unsigned long* lens = mysql_fetch_lengths(res); int fnum = mysql_num_fields(res);//獲取每一列的字段長(zhǎng)度 filename = "out_"; filename += row[1]; fstream out(filename, ios::out | ios::binary); if (!out.is_open()) { cout << "open file " << filename << " failed" << endl; } out.write(row[2], lens[2]); out.close(); mysql_close(&mysql); mysql_library_end(); getchar(); return 0; }
存儲(chǔ)過程的創(chuàng)建和使用
#include<iostream> #include<mysql.h> #include<thread> #include<sstream> #include<map> using namespace std; int main() { //1.創(chuàng)建句柄 MYSQL mysql; //2.初始化mysql mysql_init(&mysql); const char* host = "127.0.0.1"; const char* user = "root"; const char* pwd = "Z20020803"; const char* db = "database1"; //設(shè)定字符集 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); //3.連接數(shù)據(jù)庫 //一次性執(zhí)行多條語句,mysql_real_connect 函數(shù)的最后一個(gè)參數(shù)設(shè)置 if (!mysql_real_connect(&mysql, host, user, pwd, db, 3306, 0, CLIENT_MULTI_STATEMENTS))//阻塞函數(shù) { cout << "connect fail, " << mysql_error(&mysql) << endl; } else { cout << "mysql connect " << host << "success" << endl; } string sql = ""; //1.創(chuàng)建存儲(chǔ)過程 sql = "CREATE PROCEDURE p_test(IN p_in INT, OUT p_out INT, INOUT p_inout INT)\ BEGIN\ select p_in, p_out, p_inout;\ set p_in = 100, p_out = 200, p_inout = 300;\ select p_in, p_out, p_inout;\ END"; int re = mysql_query(&mysql, sql.c_str()); if (re != 0) { cout << mysql_error(&mysql) << endl; } //2.定義數(shù)據(jù)庫的變量,并且賦值 cout << "A = 1, B = 2, C = 3" << endl; sql = "SET @A=1;SET @B=2;SET @C=3;"; re = mysql_query(&mysql, sql.c_str()); if (re != 0) { cout << mysql_error(&mysql) << endl; } //需要獲取結(jié)果集并且釋放 do { cout << "set affected " << mysql_affected_rows(&mysql) << endl; } while (mysql_next_result(&mysql) == 0);// 等于0表示還有結(jié)果,等于-1表示沒有結(jié)果了,大于0表示出錯(cuò) //3.調(diào)用存儲(chǔ)過程 sql = "call p_test(@A,@B,@C)"; re = mysql_query(&mysql, sql.c_str()); if (re != 0) { cout << "select " << mysql_error(&mysql) << endl; } cout << "in proce:"; do { MYSQL_RES* res = mysql_store_result(&mysql); if (!res) { continue; } //字段數(shù)量 int fcount = mysql_num_fields(res); //打印結(jié)果集 for (;;) { MYSQL_ROW row = mysql_fetch_row(res); if (!row) { break; } for (int i = 0; i < fcount; i++) { if (row[i]) { cout << row[i] << " "; } else { cout << "NULL "; } } cout << endl; } mysql_free_result(res); } while (mysql_next_result(&mysql) == 0); //獲取存儲(chǔ)過程 sql = "select @A,@B,@C"; re = mysql_query(&mysql, sql.c_str()); if (re != 0) { cout << mysql_error(&mysql) << endl; } MYSQL_RES* res1 = mysql_store_result(&mysql); MYSQL_ROW row = mysql_fetch_row(res1); int num = mysql_num_fields(res1); for (int i = 0; i < num; i++) { cout << row[i] << " "; } mysql_free_result(res1); mysql_close(&mysql); mysql_library_end(); getchar(); return 0; }
總結(jié)
到此這篇關(guān)于C++連接mysql數(shù)據(jù)庫的文章就介紹到這了,更多相關(guān)C++連接mysql內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vs2019配置Qt5開發(fā)環(huán)境(圖文教程)
本文主要介紹了如何使用visual studi2019配置qt5開發(fā)環(huán)境,以及創(chuàng)建qt項(xiàng)目,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12

C++ 使用PrintWindow實(shí)現(xiàn)窗口截圖功能

詳解C++類的成員函數(shù)做友元產(chǎn)生的循環(huán)依賴問題