1. 程式人生 > >C++使用MySql++操作資料庫例項

C++使用MySql++操作資料庫例項

有朋友讓幫忙寫個C++修改資料庫中使用者名稱密碼的工具,因為他是做VPN的,要給很多客戶端展示訪問速度等,有一個固定的使用者名稱來展示,但是每次給使用者試用的是不同的密碼,是隨機生成的。

所以就想到了用MySql++這個資料庫操作類庫,我們專案中也是用這個的,非常好用。

MySql++簡介:

MySQL++ is a C++ wrapper for MySQL’s C API. It is built around the same principles as the Standard C++ Library, to make dealing with the database as easy as dealing with STL containers. In addition, MySQL++ provides facilities that let you avoid the most repetitive sorts of SQL within your own code, providing native C++ interfaces for these common tasks.

MySql++下載地址:

安裝MySql  Server在本機上,需要其中的庫和標頭檔案來編譯,安裝過程就不介紹了。

解壓Mysql++後,裡面有VS的工程檔案,2003、2005、2008,我使用的是VS2010,所以挑了一個最近的2008工程來update。

單獨編譯mysqlpp工程,因為其他的工程都是例子和測試程式碼,可以看看,但是沒必要編譯。

注意:可能會提示mysql_version.h檔案無法找到,請開啟專案屬性配置,看看MySql的配置路徑是否正確。

使用其中的 install.hta 檔案來拷貝一份 .h .lib .dll檔案,都是我們的工程中需要的檔案,這樣一份完整的MySql++的靜態動態庫就準備好了。

在我們的工程中加入標頭檔案和靜態庫目錄(這些大家應該都是輕車熟路的,我就不再贅述了)。

下來就是編寫我們的程式碼來操作資料庫了,當然了,在這之前,你的mysql服務要安裝好,並且建立一個要使用的資料庫和表來操作。

[cpp]
#include <winsock2.h> // 因為要使用socket,所以需要包含socket2.1標頭檔案
#include "mysql++.h" // Mysql++標頭檔案
#include <string>
#include <iostream>
using namespace mysqlpp;
using namespace std;

const DWORD SpaceTime = 20 * 60 * 1000; // 20分鐘
const int LEN_NAME = 8;
const char CCH[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 隨機字串字典

// 簡單的隨機字串生成函式
char* rand_password( char* str, int len )
{
int i = 0, n = 0;
int nLength = strlen( CCH );
for ( i = 0, n = 0; i < LEN_NAME && n < nLength; ++i, ++n )
{
int x = rand() % ( nLength – 1 );
str[i] = CCH[x];
}

str[ i + 1 ] = ‘\0’;
return str;
}

int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "VPN_Modify_MySql_User_Password Tool" << std::endl;
std::cout << "Copyright (C) eliteYang" << std::endl;
std::cout << "http://www.cppfans.org" << std::endl;

mysqlpp::Connection _vpnConn;
// 設定資料庫編碼
_vpnConn.set_option( new mysqlpp::SetCharsetNameOption( "utf8" ) );

string dbIp, dbUserName, dbPwd, dbName;
cout << "\n\n\nMySql DataBase Info Input" << endl;
cout << "請輸入MySQL伺服器IP地址 : ";
cin >> dbIp;

cout << "請輸入MySql管理員賬號 : ";
cin >> dbUserName;

cout << "請輸入MySql管理員賬號密碼 : ";
cin >> dbPwd;

cout << "請輸入MySql資料庫名 : ";
cin >> dbName;

cout << " 預設埠號為 3306 " << endl;

bool bConnect = _vpnConn.connect( dbName.c_str(), dbIp.c_str(), dbUserName.c_str(), dbPwd.c_str(), 3306 );
if ( !bConnect )
{
cout << "VPN Connect mysql failed! Error: " << _vpnConn.error() << endl;
system( "Pause" );
return -1;
}
else
{
cout << "VPN Connect mysql success!" << endl;
}

DWORD timeSlot = timeGetTime();
char szChar[ 256 ] = { 0 };
string strName = "123";
cout << "請輸入需要定時修改密碼的使用者名稱 :";
cin >> strName;

sprintf_s( szChar, "select * from vpn_user_info where UserName=%s", strName.c_str() );
while ( true )
{
if ( timeGetTime() – timeSlot < SpaceTime )
{ continue; }
try
{
mysqlpp::Query _query = _vpnConn.query( szChar );
mysqlpp::StoreQueryResult _result = _query.store();
if ( _result.num_rows() != 1 )
{
cout << "UserName[123] repeat, please check" << endl;
timeSlot = timeGetTime();
continue;
}

string strUserName = _result[0][0].c_str();
string strUserPassword = _result[0][1].c_str();
cout << "CurentInfo UserName[ " << strUserName.c_str() << " ] Password[ " << strUserPassword.c_str() << " ]" << endl;

char strTemp[ LEN_NAME + 1 ] = { 0 };
strUserPassword = rand_password( strTemp, LEN_NAME );

char szTemp[ 256 ] = { 0 };
sprintf_s( szTemp, "UPDATE vpn_user_info SET Password = ‘%s’ WHERE UserName = ‘%s’;", strUserPassword.c_str(), strUserName.c_str() );
_query << szTemp << endl;
_query.execute();
cout << "ModifyUserInfo UserName[ " << strUserName.c_str() << " ] Password[ " << strUserPassword.c_str() << " ]" << endl;
}
catch (const mysqlpp::BadQuery& er)
{
// Handle any query errors
cerr << "Query error: " << er.what() << endl;
return -1;
}
catch (const mysqlpp::BadConversion& er)
{
// Handle bad conversions
cerr << "Conversion error: " << er.what() << endl <<
"\tretrieved data size: " << er.retrieved <<
", actual size: " << er.actual_size << endl;
return -1;
}
catch (const mysqlpp::Exception& er)
{
// Catch-all for any other MySQL++ exceptions
cerr << "Error: " << er.what() << endl;
return -1;
}
}

_vpnConn.disconnect();
system( "Pause" );

return 0;
}
[/cpp]

裡面的異常catch是比較多的,不過有異常捕獲總比沒有好,出了問題還可以看異常。
以上就是一個完整的使用MySql++操作資料庫的例子,其實可以使用config或者ini配置整個資料庫的資訊,使用Log4cxx來列印Log,想想還是算了,看來是被專案中整套的庫給慣懶了。
Mysql++中很多值得去看的地方,很好用,封轉的很好,當然了,你也可以直接使用MySql的庫,也是可以的,不過就沒有這麼舒服了,主要是MySql++封裝了輸入輸出流,讓整個操作看起來容易了。
以上程式碼可以編譯過,並可以使用,均為本人親測,如有問題,歡迎交流。

PS:oracle還有一個工具叫MySql Connecter for C++,這個工具也是很簡潔的,但是畢竟太新了,大家還沒接受,這個庫的優點是非常乾淨,沒有libmysql.lib的C-Lib,不過它裡面有一個MySQL C++ Driver是基於JDBC4.0規範事先的,所以不太喜歡,下一篇會用這個庫寫一個例子給大家看。