有朋友让帮忙写个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++下载地址:
http://tangentsoft.net/mysql++/ (最新版本是3.1.0)
安装MySql Server在本机上,需要其中的库和头文件来编译,安装过程就不介绍了。
解压Mysql++后,里面有VS的工程文件,2003、2005、2008,我使用的是VS2010,所以挑了一个最近的2008工程来update。
单独编译mysqlpp工程,因为其他的工程都是例子和测试代码,可以看看,但是没必要编译。
注意:可能会提示mysql_version.h文件无法找到,请打开项目属性配置,看看MySql的配置路径是否正确。
使用其中的 install.hta 文件来拷贝一份 .h .lib .dll文件,都是我们的工程中需要的文件,这样一份完整的MySql++的静态动态库就准备好了。
在我们的工程中加入头文件和静态库目录(这些大家应该都是轻车熟路的,我就不再赘述了)。
下来就是编写我们的代码来操作数据库了,当然了,在这之前,你的mysql服务要安装好,并且建立一个要使用的数据库和表来操作。
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
|
#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规范事先的,所以不太喜欢,下一篇会用这个库写一个例子给大家看。