C#寫一套最全的MySQL幫助類(包括增刪改查)

2023-04-21 12:01:15

介紹說明:
這個幫助類包含了六個主要的方法:
ExecuteNonQuery、ExecuteScalar、ExecuteQuery、ExecuteQuery(泛型)、Insert、Update和Delete。
其中,ExecuteNonQuery用於執行不返回結果集的SQL語句;
ExecuteScalar用於執行一個查詢,並返回結果集中第一行的第一列;
ExecuteQuery用於執行一個查詢,並返回結果集;
ExecuteQuery(泛型)用於執行一個查詢,並將結果集對映到一個物件列表;
Insert用於向資料庫中插入資料;
Update用於更新資料庫中的資料;
Delete用於刪除資料庫中的資料。

一、以下是一個基於C#的MySQL幫助類的範例程式碼,可以用於連線資料庫、執行SQL語句、讀取資料等操作:

using System;
using System.Collections.Generic;
using System.Data;
using MySql.Data.MySqlClient;

public class MySQLHelper
{
    private string connectionString;

    public MySQLHelper(string connectionString)
    {
        this.connectionString = connectionString;
    }

    // 執行不返回結果集的SQL語句
    public int ExecuteNonQuery(string sql, params MySqlParameter[] parameters)
    {
        using (MySqlConnection connection = new MySqlConnection(connectionString))
        {
            using (MySqlCommand command = new MySqlCommand(sql, connection))
            {
                // 新增引數
                command.Parameters.AddRange(parameters);
                // 開啟連線
                connection.Open();
                // 執行SQL語句並返回影響行數
                return command.ExecuteNonQuery();
            }
        }
    }

    // 執行一個查詢,並返回結果集中第一行的第一列
    public object ExecuteScalar(string sql, params MySqlParameter[] parameters)
    {
        using (MySqlConnection connection = new MySqlConnection(connectionString))
        {
            using (MySqlCommand command = new MySqlCommand(sql, connection))
            {
                // 新增引數
                command.Parameters.AddRange(parameters);
                // 開啟連線
                connection.Open();
                // 執行SQL查詢並返回第一行第一列的值
                return command.ExecuteScalar();
            }
        }
    }

    // 執行一個查詢,並返回結果集
    public DataTable ExecuteQuery(string sql, params MySqlParameter[] parameters)
    {
        using (MySqlConnection connection = new MySqlConnection(connectionString))
        {
            using (MySqlCommand command = new MySqlCommand(sql, connection))
            {
                // 新增引數
                command.Parameters.AddRange(parameters);
                // 開啟連線
                connection.Open();
                // 建立DataAdapter和DataTable物件,並填充資料
                using (MySqlDataAdapter adapter = new MySqlDataAdapter(command))
                {
                    DataTable dataTable = new DataTable();
                    adapter.Fill(dataTable);
                    return dataTable;
                }
            }
        }
    }

    // 執行一個查詢,並將結果集對映到一個物件列表
    public List<T> ExecuteQuery<T>(string sql, Func<IDataRecord, T> selector, params MySqlParameter[] parameters)
    {
        using (MySqlConnection connection = new MySqlConnection(connectionString))
        {
            using (MySqlCommand command = new MySqlCommand(sql, connection))
            {
                // 新增引數
                command.Parameters.AddRange(parameters);
                // 開啟連線
                connection.Open();
                // 建立DataReader物件並讀取資料,將每行資料對映到物件並新增到列表中
                using (MySqlDataReader reader = command.ExecuteReader())
                {
                    List<T> list = new List<T>();
                    while (reader.Read())
                    {
                        list.Add(selector(reader));
                    }
                    return list;
                }
            }
        }
    }

    // 向資料庫中插入資料
    public int Insert(string tableName, Dictionary<string, object> data)
    {
        string[] columns = new string[data.Count];
        object[] values = new object[data.Count];

        int i = 0;
        foreach (KeyValuePair<string, object> item in data)
        {
            // 獲取列名和值
            columns[i] = item.Key;
            values[i] = item.Value;
            i++;
        }

        string sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", tableName, string.Join(",", columns), "@" + string.Join(",@", columns));

        // 將Dictionary轉換為MySqlParameter陣列,並執行SQL語句
        return ExecuteNonQuery(sql, ToMySqlParameters(data));
    }

    // 更新資料庫中的資料
    public int Update(string tableName, Dictionary<string, object> data, string whereClause = "")
    {
        string[] setValues = new string[data.Count];
        int i = 0;
        foreach (KeyValuePair<string, object> item in data)
        {
            // 獲取列名和值
            setValues[i] = string.Format("{0}=@{0}", item.Key);
            i++;
        }

        string sql = string.Format("UPDATE {0} SET {1}", tableName, string.Join(",", setValues));

        if (!string.IsNullOrEmpty(whereClause))
        {
            sql += " WHERE " + whereClause;
        }

        // 將Dictionary轉換為MySqlParameter陣列,並執行SQL語句
        return ExecuteNonQuery(sql, ToMySqlParameters(data));
    }

    // 刪除資料庫中的資料
    public int Delete(string tableName, string whereClause = "")
    {
        string sql = string.Format("DELETE FROM {0}", tableName);

        if (!string.IsNullOrEmpty(whereClause))
        {
            sql += " WHERE " + whereClause;
        }

        // 執行SQL語句並返回影響

        return ExecuteNonQuery(sql);
    }
    // 將Dictionary轉換為MySqlParameter陣列
    private MySqlParameter[] ToMySqlParameters(Dictionary<string, object> data)
    {
        List<MySqlParameter> parameters = new List<MySqlParameter>();

        foreach (KeyValuePair<string, object> item in data)
        {
            parameters.Add(new MySqlParameter("@" + item.Key, item.Value));
        }

        return parameters.ToArray();
    }
}
View Code

二、另外,在使用這個幫助類時,需要先建立一個連線字串,例如

string connectionString = "server=localhost;database=myDatabase;uid=myUsername;password=myPassword;";
MySQLHelper mySQLHelper = new MySQLHelper(connectionString);
View Code

三、然後就可以使用這個幫助類來存取MySQL資料庫了。下面是一些範例程式碼:

// 查詢所有資料
DataTable dataTable = mySQLHelper.ExecuteQuery("SELECT * FROM myTable");
foreach (DataRow row in dataTable.Rows)
{
    Console.WriteLine(row["column1"].ToString());
}


// 查詢單個值
object value = mySQLHelper.ExecuteScalar("SELECT COUNT(*) FROM myTable");
Console.WriteLine(value.ToString());


// 查詢並對映到物件列表
List<MyClass> list = mySQLHelper.ExecuteQuery("SELECT * FROM myTable", r => new MyClass
{
    Column1 = r["column1"].ToString(),
    Column2 = int.Parse(r["column2"].ToString())
});


// 插入資料
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("column1", "value1");
data.Add("column2", 123);
int result = mySQLHelper.Insert("myTable", data);


// 更新資料
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("column1", "value2");
data.Add("column2", 456);
int result = mySQLHelper.Update("myTable", data, "id=1");


// 刪除資料
int result = mySQLHelper.Delete("myTable", "id=1");
View Code

               注:這些範例程式碼展示瞭如何使用這個幫助類來執行常見的MySQL操作,例如查詢、插入、更新和刪除資料。請注意,在執行SQL語句時,要避免SQL隱碼攻擊,可以使用引數化查詢來確保安全。

四、就上述SQL隱碼攻擊,防範例子:

//是的,使用引數化查詢是避免SQL隱碼攻擊的重要方法之一。C#中可以使用MySqlParameter類來建立引數化查詢,下面簡單介紹一下如何使用MySqlParameter類。
//首先,看一個普通的SQL語句:
      string sql = "SELECT * FROM Users WHERE name='" + userName + "' AND password='" + password + "'";
//這個SQL語句接收兩個字串型別的引數:userName和password。但是,如果惡意使用者在輸入使用者名稱或密碼時新增了SQL程式碼,則可能會導致SQL隱碼攻擊。例如,如果使用者輸入了以下內容作為密碼:
      a' OR 'a'='a
 //則生成的SQL語句將變成:
      SELECT* FROM Users WHERE name='xxx' AND password = 'a' OR 'a'='a'
//這個SQL語句將始終返回true,因為'a'='a'是永遠成立的,所以使用者可以繞過登入驗證並存取資料庫。

//為了避免這種情況發生,我們可以使用MySqlParameter類來建立引數化查詢。以下是一個範例:
      string sql = "SELECT * FROM Users WHERE name=@UserName AND password=@Password";
      using (MySqlConnection connection = new MySqlConnection(connectionString))
      {
          using (MySqlCommand command = new MySqlCommand(sql, connection))
          {
              // 建立引數
              command.Parameters.Add(new MySqlParameter("@UserName", userName));
              command.Parameters.Add(new MySqlParameter("@Password", password));
              
              // 開啟連線並執行查詢
              connection.Open();
              using (MySqlDataReader reader = command.ExecuteReader())
              {
                  // 處理結果集
              }
          }
      }
//在這個範例中,我們使用了 @符號來標記引數名稱,並使用MySqlParameter類為每個引數建立範例。這樣,即使使用者在輸入使用者名稱或密碼時新增了SQL程式碼,它也不會影響生成的SQL語句。
//總之,使用引數化查詢是一個非常重要的安全措施,可以有效預防SQL隱碼攻擊,C#提供了方便易用的MySqlParameter類來支援引數化查詢。
View Code