对不起,如果你填补无聊。我搜索了几个搜索引擎,但没有得到任何结果。无论如何,我在一个应用程序中工作,该数据库是mysql。现在我已经创建了一个数据库包装器类,并想检查连接是否已经打开。你可以帮助我吗?
String^ constring = L"datasource=localhost;port=3306;username=root;password=pass;database=eps;";
String^ my_query = L"select id from eps_users where usr = '" + this->user_name->Text + "' and psw = md5('" + this->pass_word->Text + "');";
MySqlConnection^ conDatabase = gcnew MySqlConnection(constring);
MySqlCommand^ cmd = gcnew MySqlCommand(my_query, conDatabase);
MySqlDataReader^ myreader;
try
{
conDatabase->Open();
myreader = cmd->ExecuteReader();
int count = 0;
while (myreader->Read())
{
count = count + 1;
}
if (count == 1){
MessageBox::Show("Username And Password is correct.", "Success", MessageBoxButtons::OK,
MessageBoxIcon::Information);
this->Hide();
Form2^ f2 = gcnew Form2(constring);
f2->ShowDialog();
}
else{
MessageBox::Show("Username And Password is not correct.", "Error", MessageBoxButtons::OK,
MessageBoxIcon::Error);
// <del>
this->Hide();
Form2^ f2 = gcnew Form2(constring);
f2->ShowDialog();
// </del>
}
}
catch (Exception^ ex)
{
MessageBox::Show(ex->Message);
}
conDatabase->Close();
我需要检查是否(conDatabase-&gt; HasBeenOpened()){conDatabase-&gt; Open();}
答案 0 :(得分:0)
MySqlConnection类型实现了一个称为连接池的功能,它依赖于垃圾收集器来帮助回收与数据库的连接,因此关于连接对象的最佳实践是为大多数数据库调用创建一个全新的对象,这样垃圾收集器就可以正确地回收旧的垃圾收集器。过程如下:
所有四个步骤都位于单个try / catch / finally块中。 (此外,配置步骤需要在finally块内部进行!)因为您通常从一个全新的连接对象开始,所以通常不需要检查它是否先打开:您知道它已关闭。调用Open()
后,您也不需要检查状态:该方法将一直阻塞直到它完成,如果失败则抛出异常。
但是,如果你真的处于(罕见的)情况之一,在一段时间内保持连接是一个好主意,你可以像这样检查状态:
if( conDatabase->State == ConnectionState::Open)
现在,我想谈谈的代码还有另外一个问题。问题归结为:如果我将以下内容放入您的用户名文本框中,您认为会发生什么:
';DROP Table eps_users;--
如果您认为它会尝试在您的数据库中执行该DROP语句,那么您就是对的:它会!也可以进行更微妙和破坏性的查询。这是一个巨大的问题:有些机器人运行全职抓取网站寻找滥用此方法的方法,甚至企业内部桌面应用程序也会不时被抓住。要解决此问题,您需要对每个实例使用参数化查询,其中包含用户提供的数据作为sql语句的一部分。
一个简单的例子可能如下所示:
String^ my_query = L"select id from eps_users where usr = @userID;";
MySqlCommand^ cmd = gcnew MySqlCommand(my_query, conDatabase);
cmd->Parameters->AddWithValue(L"@userID", this->user_name->Text);