2012-01-15 94 views
2

在我目前編寫的應用程序中,我處理了很多MySql數據庫。我知道我這樣做的方式是錯誤的,所以你不需要告訴我,但我該如何正確地做到這一點?如同從.NET應用程序處理MySql數據庫的正確做法是什麼。什麼是從.Net應用程序處理MySql數據庫的正確方法

在一分鐘我用一個類,這是下面:

using System; 
using MySql.Data.MySqlClient; 

namespace WhateverProjectImWorkingOn 
{ 
    class MySql 
    { 
     public string myConnectionString = String.Format("SERVER={0}; DATABASE={1}; UID={2}; PASSWORD={3}", "8.8.8.8", "foobar", "foo", "barr"); 

     public string Select(string mySqlQuery) 
     { 
      MySqlConnection connection = new MySqlConnection(myConnectionString); 
      MySqlCommand command = connection.CreateCommand(); 
      MySqlDataReader Reader; 

      command.CommandText = mySqlQuery; 

      connection.Open(); 

      Reader = command.ExecuteReader(); 

      string thisrow = ""; 

      while (Reader.Read()) 
      { 
       for (int i = 0; i < Reader.FieldCount; i++) 
       { 
        thisrow += Reader.GetValue(i).ToString(); 
       } 
      } 

      Reader.Close(); 
      connection.Close(); 
      return thisrow; 
     } 

     public void Update(string mySqlQuery) 
     { 
      MySqlConnection mangoConnection = new MySqlConnection(myConnectionString); 
      MySqlCommand command = mangoConnection.CreateCommand(); 

      command.CommandText = mySqlQuery; 

      mangoConnection.Open(); 
      MySqlDataReader reader = command.ExecuteReader(); 
      mangoConnection.Close(); 
     } 
    } 
} 

我實例化這個類,然後使用選擇的方法來選擇,像這樣的數據:

MySql mySql = new MySql(); 
string whateverIWant = mySql.Select("Select `MyValue` From `FooBarr` Where `Foo` = 'Barr'"); 

我跑更新查詢像這樣:

mySql.Update("UPDATE `tblFooBarr` SET `acme`='Foo' WHERE `tnt`='barr';"); 

在你開始之前,是的,我爲自己的sl sl sl code的代碼感到非常羞愧,但如果你能幫助我提高,我會非常感激!

謝謝

+3

你應該包裝在using語句您的MySqlConnection類,以確保即使出現錯誤,連接也會關閉。 – Hans 2012-01-15 17:47:19

+0

這似乎是可行的,那麼我的代碼中的原始SQL呢?我的理解是,這只是一個龐大的nono,對連接參數進行硬編碼。 – JMK 2012-01-15 17:49:56

+3

您還應該使用類型安全的MySqlParameter來防止SQL注入代碼。對於SQL注入,請參閱以下鏈接http://msdn.microsoft.com/en-us/library/ff648339.aspx。 – Hans 2012-01-15 18:21:21

回答

6

首先,我會創建一個接口,將您的MySql數據庫和您的代碼放在一起。這將您的應用程序從MySql數據庫類中分離出來;是這樣的:

public interface IDbProvider : IDisposable 
{ 
    void Open(); 
    void BeginTransaction(); 
    IDataReader ExecuteReader(string query); 
    int ExecuteNonReader(string query); 
    int GetLastInsertId(); 
    void Commit(); 
    void Rollback(); 
    void Close(); 
} 

在你的MySQL特有IDbProvider實現你應該從ConfigurationManager.ConnectionStrings集合連接字符串,而不是硬編碼。

接下來,你可以把你的查詢在自定義配置部分,其獲取硬編碼,MySQL的語法特定查詢出你的代碼,就像這樣:

<queries> 
    <SelectFoo> 
    <![CDATA 
    Select `MyValue` From `FooBarr` Where `Foo` = '{value}' 
    ]> 
    </SelectFoo> 
</queries> 

...然後使用自定義配置提供商通過枚舉和庫類,從知識解耦應用程序公開這些查詢到您的應用程序它使用SQL:

public enum AvailableQuery 
{ 
    SelectFoo 
} 

public class QueryLibrary 
{ 
    private readonly AvailableQueryConfigSection _availableQueries; 

    public QueryLibrary() 
    { 
     this._availableQueries = 
      (AvailableQueryConfigSection) 
      ConfigurationManager.GetSection("queries"); 
    } 

    public string GetQuery(AvailableQuery query) 
    { 
     // return query from availableQueries 
    } 
} 

最後,你可以有一個repository類使用QueryLibrary得到查詢發送到IDbProvider所以它可以返回一個對象或執行更新,這完全解耦從數據庫應用程序:

public class FooRepository 
{ 
    public Foo GetFooByValue(string value) 
    { 
     string query = this._queryLibrary 
      .GetAvailableQuery(AvailableQuery.SelectFoo) 
      .Replace("{value}", value); // <- or better still, use parameters 

     using (IDataReader reader = this._dbProvider.ExecuteReader(query)) 
     { 
      // Or get the values out of the reader here and pass them into 
      // a constructor instead of passing in the reader itself: 
      return new Foo(reader); 
     } 
    } 
} 

顯然有一堆的錯誤處理,依賴注入的設置和其他的東西去在那裏,但希望ully這應該給你一個結構從:)

+0

這很棒,我知道必須有更好的方式來做到這一點!謝謝! – JMK 2012-01-16 07:56:54

+0

不客氣,祝你好運:) – 2012-01-16 09:37:53

3

這裏沒有具體的MySQL。如果你正在處理多個DBMS,那麼一種方法是使用.net db接口IDbCommand,IDbConnection等。

將連接字符串放在app.config或其他類中。

原始SQL在你的代碼中,不好?你可以看看實體框架,LinQToSQL,一個基於存儲過程的設計,但這是一個好去處,學習和看看有什麼適合。很多原始SQL的真正問題是,您的代碼與您的後端密切相關。管理這個技巧的訣竅是「把它放在一個地方」。一個'model'.dll,每個類中的一個接口。一次類來處理每個表等。不要亂丟你的代碼庫。通過遍歷整個代碼庫,因爲您重命名了訂單表,這是不行的。

你爲什麼在Update()方法中使用讀取器? 命令有一個方法。

正如@Hans所說的那樣使用,你會在整個地方發現潛在的資源泄漏。

+0

謝謝,我更新了從MySql到DBMS的標籤,並且對於回覆,它幫助了很多! – JMK 2012-01-16 07:54:57

0

開始擴大TrueWill的評論:

照顧會話類型,鎖定交易等,這取決於你的需求進行併發

Here is a tutorial

相關問題