由于工作需要抽出一周的時間來研究c/c++訪問各種數據庫的方法,并打算封裝一套c類,現在奉上最簡單的一部分:在c下訪問c。
想用C++寫項目,數據庫是必須的,所以這兩天學了一下C++操作MySQL數據庫的方法。也沒有什么教程,就是在網上搜的知識,下面匯總一下。
連接MySQL數據庫有兩種方法:第一種是使用ADO連接,不過這種只適合Windows平臺;第二種是c自己的C ccc。我是在Linux平臺下開發,所以就采用第二種方法,有很多Api函數,但是常用的就幾個,我也是就用到其中的幾個。
API函數
1.mysql_real_connect()
立即學習“C++免費學習筆記(深入)”;
連接一個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*連接句柄。如果連接失敗,返回c。對于成功的連接,返回值與第1個參數的值相同
2.c()
返回一個結果表,假定查詢成功,可以調用 c() 來查看對應于 SELECT 語句返回了多少行,或者調用 c() 來查看對應于 c,INSERT,REPLACE 或 UPc 語句影響到了多少行。
3.mysql_store_result()
MYSQL_RES?*mysql_store_result(MYSQL?*mysql)
檢索完整的結果集至客戶端。客戶端處理結果集最常用的方式是通過調用mysql_store_result(),一次性地檢索整個結果集。該函數能從服務器獲得查詢返回的所有行,并將它們保存在客戶端。對于成功檢索了數據的每個查詢(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),必須調用mysql_store_result()或mysql_use_result() 。對于其他查詢,不需要調用mysql_store_result()或mysql_use_result(),但是如果在任何情況下均調用了mysql_store_result(),它也不會導致任何傷害或性能降低。
4.mysql_num_rows()
返回結果集中的行數。
5.c()
返回結果集中的字段數,如果失敗,則返回 false。
6.c()
MYSQL_FIELD* mysql_fetch_field(MYSQL_RES *result);
獲取下一個表字段的類型,結束返回NULL。
7.c()
MYSQL_ROW?mysql_fetch_row(MYSQL_RES?*result);
從結果集中獲取下一行,成功返回一個c,值大于0。
8.mysql_fetch_field_cect()
MYSQL_FIELD*?mysql_fetch_field_direct(MYSQL_RES?*result,?int?i);
給定字段編號,返回表字段的類型,結束返回NULL。
簡單的學生信息管理代碼
光看也記不住啊,就用這些函數寫了一個學生信息管理界面,唉,去年這時候c課程設計,當時還不知道用數據庫,全用文件寫的,知道晚了很后悔啊。。。。下面是代碼:
?/************************************************************************* ???>?File?Name:?student.cpp ???>?Author:?Tanswer_? ???>?Mail:?98duxm@gmail.com ???>?Created?Time:?2017年05月28日?星期日?16時50分34秒 ?************************************************************************/ ?????????? ?#include?<iostream> ?#include?<string>? ?#include?<stack>? ?#include?<algorithm> ?#include?<sstream> ?#include?<mysql> ?#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?>?fname; ???┊??cout?>?fsex; ???┊??cout?>?fage; ???┊??cout?>?ftel; ???┊??cout?>?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',??????????'陜西省西安市雁塔區');"; ???┊??mysql_query(&mysql,sql.c_str()); ???┊??┊??????????????? ???┊??cout?>?choice;???????????????????????????????????????????????? ???}while(choice?==?'y');??????? ???????????????????? ?}??????????????????? ???????????????????? ?void?Select()????????????? ?{??????????????????? ???int?id;?????????????? ???cout?>?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?name?>?id;?????????? ???┊??cout?>?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); ???/*連接數據庫*/ ???if(!mysql_real_connect(&mysql,"localhost","root","dxm242012","Student",0,NULL,0)) ???{????? ???┊??cout?>?choice; ??? ???┊??cout?<p>C++封裝MyDB類</p> <p>后來又把這些函數簡單的封裝了一下,方便以后直接用。</p> <pre class="brush:cpp;">?/************************************************************************* ???>?File?Name:?myDB.h ???>?Author:?Tanswer_ ???>?Mail:?98duxm@gmail.com ???>?Created?Time:?2017年05月28日?星期日?22時26分22秒 ?************************************************************************/ ?? ?#ifndef?_MYDB_H ?#define?_MYDB_H ?? ?#include?<string> ?#include?<iostream> ?#include?<mysql> ?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:?98duxm@gmail.com ???>?Created?Time:?2017年05月28日?星期日?22時27分18秒 ?************************************************************************/ ? ?#include?<iostream> ?#include?<string> ?#include?<stack> ?#include?<algorithm>??? ?#include?<mysql>? ?#include?"myDB.h" ? ?using?namespace?std; ? ?MyDB::MyDB()??? ?{ ???mysql?=?mysql_init(NULL); ???if(mysql?==?NULL) ???{ ???┊??cout??File?Name:?main.cpp ???>?Author:?Tanswer_ ???>?Mail:?98duxm@gmail.com ???>?Created?Time:?2017年05月28日?星期日?22時53分43秒 ?************************************************************************/ ???? ?#include?<iostream> ?#include?<string> ?#include?<stack> ?#include?<algorithm> ?#include?<mysql> ?#include?"myDB.h" ???? ?using?namespace?std; ???? ???? ?int?main() ?{??? ???MyDB?db; ???db.InitDB("localhost","root","xxxxxx","Student"); ???db.ExeSQL("SELECT?*?FROM?Infor;"); ???return?0; ?}</mysql></algorithm></stack></string></iostream></mysql></algorithm></stack></string></iostream></mysql></iostream></string>
以下是運行結果:
下面是遇到的問題:
1. 編譯時出錯
沒有那個文件或目錄?
#include<mysql>? ^</mysql>
編譯中斷。
解決:除了mysql-client和mysql-server,又c了mysql-devel,然后就解決了。
2. 自定義的c傳入sql語句時,出現問題
在網上查找到這樣一種格式,
string sql = “INSERT INTO Infor (name,sex,tel,addr,age) values(‘”+fname+”‘,'”+fsex+”‘,'”+ftel+”‘,'”+faddr+”‘, “+IntToStr(fage)+”);”;
然后string類型的可以成功,整型的變量還是不行,我又寫了個函數把int轉為string。
?string?IntToStr(int?num) ?{????????? ???stringstream?ss; ???ss.clear(); ???ss?