想用C++寫(xiě)項(xiàng)目,數(shù)據(jù)庫(kù)是必須的,所以這兩天學(xué)了一下C++操作MySQL數(shù)據(jù)庫(kù)的方法。也沒(méi)有什么教程,就是在網(wǎng)上搜的知識(shí),下面匯總一下。
連接MySQL數(shù)據(jù)庫(kù)有兩種方法:第一種是使用ADO連接,不過(guò)這種只適合Windows平臺(tái);第二種是使用MySQL自己的C API函數(shù)連接數(shù)據(jù)庫(kù)。我是在Linux平臺(tái)下開(kāi)發(fā),所以就采用第二種方法,有很多Api函數(shù),但是常用的就幾個(gè),我也是就用到其中的幾個(gè)。
API函數(shù)
1.mysql_real_connect()
連接一個(gè)mysql服務(wù)器
1
2
3
4
5
6
7
8
|
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*連接句柄。如果連接失敗,返回NULL。對(duì)于成功的連接,返回值與第1個(gè)參數(shù)的值相同
2.mysql_query()
執(zhí)行指定”以NULL終結(jié)的字符串”的SQL查詢(xún)
返回一個(gè)結(jié)果表,假定查詢(xún)成功,可以調(diào)用 mysql_num_rows() 來(lái)查看對(duì)應(yīng)于 SELECT 語(yǔ)句返回了多少行,或者調(diào)用 mysql_affected_rows() 來(lái)查看對(duì)應(yīng)于 DELETE,INSERT,REPLACE 或 UPDATE 語(yǔ)句影響到了多少行。
3.mysql_store_result()
1
|
MYSQL_RES *mysql_store_result(MYSQL *mysql) |
檢索完整的結(jié)果集至客戶(hù)端。客戶(hù)端處理結(jié)果集最常用的方式是通過(guò)調(diào)用mysql_store_result(),一次性地檢索整個(gè)結(jié)果集。該函數(shù)能從服務(wù)器獲得查詢(xún)返回的所有行,并將它們保存在客戶(hù)端。對(duì)于成功檢索了數(shù)據(jù)的每個(gè)查詢(xún)(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),必須調(diào)用mysql_store_result()或mysql_use_result() 。對(duì)于其他查詢(xún),不需要調(diào)用mysql_store_result()或mysql_use_result(),但是如果在任何情況下均調(diào)用了mysql_store_result(),它也不會(huì)導(dǎo)致任何傷害或性能降低。
4.mysql_num_rows()
返回結(jié)果集中的行數(shù)。
5.mysql_num_fields()
返回結(jié)果集中的字段數(shù),如果失敗,則返回 false。
6.mysql_fetch_field()
MYSQL_FIELD* mysql_fetch_field(MYSQL_RES *result);
獲取下一個(gè)表字段的類(lèi)型,結(jié)束返回NULL。
7.mysql_fetch_row()
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
從結(jié)果集中獲取下一行,成功返回一個(gè)數(shù)組,值大于0。
8.mysql_fetch_field_direct()
MYSQL_FIELD* mysql_fetch_field_direct(MYSQL_RES *result, int i);
給定字段編號(hào),返回表字段的類(lèi)型,結(jié)束返回NULL。
簡(jiǎn)單的學(xué)生信息管理代碼
光看也記不住啊,就用這些函數(shù)寫(xiě)了一個(gè)學(xué)生信息管理界面,唉,去年這時(shí)候C語(yǔ)言課程設(shè)計(jì),當(dāng)時(shí)還不知道用數(shù)據(jù)庫(kù),全用文件寫(xiě)的,知道晚了很后悔啊。。。。下面是代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
/************************************************************************* > File Name: student.cpp > Author: Tanswer_ > Mail: [email protected] > Created Time: 2017年05月28日 星期日 16時(shí)50分34秒 ************************************************************************/ #include <iostream> #include <string> #include <stack> #include <algorithm> #include <sstream> #include <mysql/mysql.h> #include <unistd.h> using namespace std; MYSQL mysql; MYSQL_ROW row; MYSQL_FIELD* field = NULL; MYSQL_RES* result; string IntToStr( int num) { stringstream ss; ss.clear(); ss << num; return ss.str(); } void Add() { string fname,fsex,ftel,faddr; int fage; char choice; do { ┊ cout << "請(qǐng)依次輸入以下信息:" << endl; ┊ cout << "\nName: " ;cin >> fname; ┊ cout << "\nSex: " ;cin >> fsex; ┊ cout << "\nAge: " ; cin >> fage; ┊ cout << "\nTel: " ; cin >> ftel; ┊ cout << "\nAddr: " ; cin >> faddr; ┊ string sql = "INSERT INTO Infor (name,sex,tel,addr,age) values('" +fname+ "','" +fsex+ "','" +ftel+ "','" +faddr+ "', " +IntToStr(fage)+ ");" ; ┊ //string sql = "INSERT INTO Infor (name,sex,age,tel,addr) values('小紅','女',18,'13333333333', '陜西省西安市雁塔區(qū)');"; ┊ mysql_query(&mysql,sql.c_str()); ┊ ┊ ┊ cout << "是否繼續(xù)添加(y/n)?: " ; ┊ cin >> choice; } while (choice == 'y' ); } void Select() { int id; cout << "請(qǐng)輸入要查詢(xún)學(xué)生的學(xué)號(hào): " ; cin >> id; string sql = "SELECT * FROM Infor WHERE id = " +IntToStr(id)+ ";" ; mysql_query(&mysql,sql.c_str()); result = mysql_store_result(&mysql); if (result == NULL) ┊ cout << "fail\n" ; for ( int i=0; i<mysql_num_fields(result); i++) { ┊ field = mysql_fetch_field_direct(result,i); ┊ cout << field->name << "\t\t" ; } cout << endl; row = mysql_fetch_row(result); while (row != NULL) { ┊ for ( int i=0; i<mysql_num_fields(result); i++) ┊ { ┊ ┊ cout << row[i] << "\t\t" ; ┊ } ┊ cout << endl; ┊ row = mysql_fetch_row(result); } } void Update() { int id; char choice; string newaddr; ┊ cout << "請(qǐng)輸入要修改同學(xué)的學(xué)號(hào): " ; ┊ cin >> id; ┊ cout << endl << "請(qǐng)輸入修改后的地址: " ; ┊ cin >> newaddr; ┊ string sql = "UPDATE Infor SET addr = '" +newaddr+ "'WHERE id= " +IntToStr(id)+ "; " ; ┊ mysql_query(&mysql,sql.c_str()); ┊ } int main() { char choice[5]; mysql_init(&mysql); /*連接數(shù)據(jù)庫(kù)*/ if (!mysql_real_connect(&mysql, "localhost" , "root" , "dxm242012" , "Student" ,0,NULL,0)) { ┊ cout << "connect fial\n" ; ┊ return -1; } while ( atoi (choice) != 'q' ) { ┊ sleep(4); ┊ system ( "clear" ); ┊ cout << "1.添加學(xué)生信息" << endl; ┊ cout << "2.查詢(xún)學(xué)生信息" << endl; ┊ cout << "3.修改學(xué)生信息" << endl; ┊ cin >> choice; ┊ cout << choice << endl; ┊ switch ( atoi (choice)) ┊ { ┊ ┊ case 1: ┊ ┊ ┊ Add(); ┊ ┊ ┊ break ; ┊ ┊ case 2: ┊ ┊ ┊ Select(); ┊ ┊ ┊ break ; ┊ ┊ case 3: ┊ ┊ ┊ Update(); ┊ ┊ ┊ break ; ┊ ┊ default : ┊ ┊ ┊ break ; ┊ } } mysql_close(&mysql); return 0; } |
C++封裝MyDB類(lèi)
后來(lái)又把這些函數(shù)簡(jiǎn)單的封裝了一下,方便以后直接用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/************************************************************************* > File Name: myDB.h > Author: Tanswer_ > Mail: [email protected] > Created Time: 2017年05月28日 星期日 22時(shí)26分22秒 ************************************************************************/ #ifndef _MYDB_H #define _MYDB_H #include <string> #include <iostream> #include <mysql/mysql.h> using namespace std; class MyDB { public : MyDB(); ~MyDB(); bool InitDB(string host,string user,string pwd,string dbname); bool ExeSQL(string sql); private : MYSQL* mysql; MYSQL* mysql; MYSQL_ROW row; MYSQL_RES* result; MYSQL_FIELD* field; }; #endif /************************************************************************* > File Name: myDB.cpp > Author: Tanswer_ > Mail: [email protected] > Created Time: 2017年05月28日 星期日 22時(shí)27分18秒 ************************************************************************/ #include <iostream> #include <string> #include <stack> #include <algorithm> #include <mysql/mysql.h> #include "myDB.h" using namespace std; MyDB::MyDB() { mysql = mysql_init(NULL); if (mysql == NULL) { ┊ cout << "Error: " << mysql_error(mysql); ┊ exit (-1); } } MyDB::~MyDB() { if (!mysql) { ┊ mysql_close(mysql); } } bool MyDB::InitDB(string host,string user,string pwd,string dbname) { /*連接數(shù)據(jù)庫(kù)*/ if (!mysql_real_connect(mysql,host.c_str(),user.c_str(),pwd.c_str(),dbname.c_str(),0,NULL,0)) { ┊ cout << "connect fial: " << mysql_error(mysql); ┊ exit (-1); } return true ; } bool MyDB::ExeSQL(string sql) { /*執(zhí)行失敗*/ if (mysql_query(mysql,sql.c_str())) { ┊ cout << "query fail: " << mysql_error(mysql); ┊ exit (1); } else { ┊ /*獲取結(jié)果集*/ ┊ result = mysql_store_result(mysql); ┊ int fieldnum = mysql_num_fields(result); ┊ for ( int i=0; i<fieldnum; i++) ┊ { ┊ ┊ row = mysql_fetch_row(result); ┊ ┊ if (row <= 0) ┊ ┊ ┊ break ; ┊ ┊ for ( int j=0; j<fieldnum; j++) ┊ ┊ { ┊ ┊ ┊ cout << row[j] << "\t\t" ; ┊ ┊ } ┊ ┊ cout << endl; ┊ } ┊ mysql_free_result(result); } return true ; } /************************************************************************* > File Name: main.cpp > Author: Tanswer_ > Mail: [email protected] > Created Time: 2017年05月28日 星期日 22時(shí)53分43秒 ************************************************************************/ #include <iostream> #include <string> #include <stack> #include <algorithm> #include <mysql/mysql.h> #include "myDB.h" using namespace std; int main() { MyDB db; db.InitDB( "localhost" , "root" , "xxxxxx" , "Student" ); db.ExeSQL( "SELECT * FROM Infor;" ); return 0; } |
以下是運(yùn)行結(jié)果:
下面是遇到的問(wèn)題:
1. 編譯時(shí)出錯(cuò)
沒(méi)有那個(gè)文件或目錄
1
2
|
#include<mysql/mysql.h> ^ |
編譯中斷。
解決:除了mysql-client和mysql-server,又安裝了mysql-devel,然后就解決了。
2. 自定義的變量傳入sql語(yǔ)句時(shí),出現(xiàn)問(wèn)題
在網(wǎng)上查找到這樣一種格式,
string sql = "INSERT INTO Infor (name,sex,tel,addr,age) values('"+fname+"','"+fsex+"','"+ftel+"','"+faddr+"', "+IntToStr(fage)+");";
然后string類(lèi)型的可以成功,整型的變量還是不行,我又寫(xiě)了個(gè)函數(shù)把int轉(zhuǎn)為string。
1
2
3
4
5
6
7
|
string IntToStr( int num) { stringstream ss; ss.clear(); ss << num; return ss.str(); } |
大概就是這樣,門(mén)衛(wèi)大叔很兇,我也很絕望,就寫(xiě)到這吧,有問(wèn)題再補(bǔ)充。
原文鏈接:http://blog.csdn.net/tanswer_/article/details/72796570