如何在自定义类中实现MySQL数据库连接的创建与开闭管理
现有代码存在的问题
- 字段初始化顺序错误:类的字段初始化逻辑会早于属性赋值、构造函数执行,你声明
connection时直接用cs作为构造参数,此时cs还未被赋值,默认是null,创建连接对象时会直接抛出参数空异常。 - 缺少状态校验:直接调用
Open/Close时没有判断连接当前状态,重复开启/关闭都会抛出运行时异常。 - 非托管资源未正确释放:
MySqlConnection属于非托管资源,你的实现没有提供正确的释放逻辑,容易出现连接泄漏。 - 连接初始化时机不合理:连接对象不需要提前创建,应该在需要开启连接的时候再初始化,避免无效对象占用资源。
正确实现示例
推荐实现IDisposable接口来处理资源释放,示例代码如下:
using MySqlConnector; // 若使用MySql.Data库替换对应命名空间即可 using System; class Sql : IDisposable { // 连接字符串设为只读,初始化后不允许修改 public string ConnectionString { get; } private MySqlConnection _connection; private bool _disposed = false; // 构造函数传入连接字符串,确保初始化时连接字符串一定有值 public Sql(string connectionString) { ConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); } // 开启连接的方法 public void Open() { if (_disposed) throw new ObjectDisposedException(nameof(Sql)); // 连接为空或者已经断开的情况下重新创建连接 if (_connection == null || _connection.State == System.Data.ConnectionState.Closed) { _connection = new MySqlConnection(ConnectionString); } if (_connection.State != System.Data.ConnectionState.Open) { _connection.Open(); } } // 关闭连接的方法 public void Close() { if (_connection != null && _connection.State == System.Data.ConnectionState.Open) { _connection.Close(); } } // 可扩展其他通用操作方法,示例:执行非查询语句 public int ExecuteNonQuery(string sql, params MySqlParameter[] parameters) { Open(); // 自动开启连接 using var cmd = new MySqlCommand(sql, _connection); if (parameters != null && parameters.Length > 0) { cmd.Parameters.AddRange(parameters); } return cmd.ExecuteNonQuery(); } // 实现IDisposable的释放逻辑 public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { // 释放托管资源 Close(); _connection?.Dispose(); _connection = null; } _disposed = true; } // 析构函数,防止用户忘记手动释放 ~Sql() { Dispose(false); } }
使用方式示例
// 建议用using包裹,作用域结束后会自动释放连接资源 using var db = new Sql("你的MySQL连接字符串"); // 执行数据库操作 var affectedRows = db.ExecuteNonQuery("UPDATE users SET name = @name WHERE id = @id", new MySqlParameter("@name", "张三"), new MySqlParameter("@id", 1));
小提示:如果是在Web框架(如ASP.NET Core)中使用,推荐直接用框架内置的数据库连接池机制,无需自己封装连接管理逻辑,避免重复造轮子。
内容的提问来源于stack exchange,提问作者Jooonnnaass
相关产品推荐
相关产品推荐

