有朋友让帮忙写个C++修改数据库中用户名密码的工具,因为他是做VPN的,要给很多客户端展示访问速度等,有一个固定的用户名来展示,但是每次给用户试用的是不同的密码,是随机生成的。
所以就想到了用MySql++这个数据库操作类库,我们项目中也是用这个的,非常好用。
MySql++简介:
MySQL++ is a C++ wrapper for�0�2MySQL’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++下载地址:
http://tangentsoft.net/mysql++/�0�2 (最新版本是3.1.0)
安装MySql �0�2Server在本机上,需要其中的库和头文件来编译,安装过程就不介绍了。
解压Mysql++后,里面有VS的工程文件,2003、2005、2008,我使用的是VS2010,所以挑了一个最近的2008工程来update。
单独编译mysqlpp工程,因为其他的工程都是例子和测试代码,可以看看,但是没必要编译。
注意:可能会提示mysql_version.h文件无法找到,请打开项目属性配置,看看MySql的配置路径是否正确。
使用其中的�0�2install.hta 文件来拷贝一份 .h .lib .dll文件,都是我们的工程中需要的文件,这样一份完整的MySql++的静态动态库就准备好了。
在我们的工程中加入头文件和静态库目录(这些大家应该都是轻车熟路的,我就不再赘述了)。
下来就是编写我们的代码来操作数据库了,当然了,在这之前,你的mysql服务要安装好,并且建立一个要使用的数据库和表来操作。
#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;
}
里面的异常catch是比较多的,不过有异常捕获总比没有好,出了问题还可以看异常。
以上就是一个完整的使用MySql++操作数据库的例子,其实可以使用config或者ini配置整个数据库的信息,使用Log4cxx来打印Log,想想还是算了,看来是被项目中整套的库给惯懒了。
Mysql++中很多值得去看的地方,很好用,封转的很好,当然了,你也可以直接使用MySql的库,也是可以的,不过就没有这么舒服了,主要是MySql++封装了输入输出流,让整个操作看起来容易了。
以上代码可以编译过,并可以使用,均为本人亲测,如有问题,欢迎交流。
PS:oracle还有一个工具叫MySql Connecter for C++,这个工具也是很简洁的,但是毕竟太新了,大家还没接受,这个库的优点是非常干净,没有libmysql.lib的C-Lib,不过它里面有一个MySQL C++ Driver是基于JDBC4.0规范事先的,所以不太喜欢,下一篇会用这个库写一个例子给大家看。
转载请注明:C++爱好者博客 » C++使用MySql++操作数据库实例