0

对不起,如果你感到无聊。我搜索了几个搜索引擎,但没有得到任何结果。无论如何,我正在一个数据库是 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();

我需要检查 if(conDatabase->HasBeenOpened()) { conDatabase->Open();}

4

1 回答 1

0

MySqlConnection 类型实现了一个称为连接池的功能,它依赖于垃圾收集器来帮助回收与数据库的连接,因此关于连接对象的最佳实践是为大多数对数据库的调用创建一个全新的对象,以便垃圾收集器可以正确回收旧的。过程是这样的:

  1. 创建新连接
  2. 打开连接
  3. 将连接用于一个查询/事务
  4. 释放连接

所有四个步骤都位于一个 try/catch/finally 块中。(此外,dispose 步骤需要在 finally 块内进行!)因为您通常从一个全新的连接对象开始,通常不需要检查它是否首先打开:您知道它已关闭。您也不需要在调用后检查状态Open():该方法将阻塞直到完成,如果失败则抛出异常。

但是,如果您确实处于(罕见的!)情况之一,最好长时间保持连接,您可以像这样检查状态:

if( conDatabase->State == ConnectionState::Open)

现在,我想谈谈该代码中的另一个问题。问题归结为:如果我将以下内容放入您的用户名文本框中,您认为会发生什么:

';删除表 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);
于 2014-04-09T21:34:31.307 回答