导读:本期聚焦于小伙伴创作的《Dapper怎么连接MySQL数据库?Dapper for MySQL配置方法详解》,敬请观看详情。直接把Dapper接到MySQL,关键并不在Dapper本身,而在底层ADO.NET驱动的选择与连接串写法。不少项目沿用旧的MySql.Data包,结果在异步批量写入时遇到线程池耗尽。改用MySqlConnector后,配合正确的连接字符串参数,吞吐明显提升。本文说明如何通过NuGet引入依赖、构造IDbConnection、写可复用的工厂方法,并给出参数化查询示例。同时指出连接未释放、字符集不匹配等常见故障点,帮助你用最少的配置跑通第一条查询。

Dapper是一个轻量级的.NET ORM,它本身不负责数据库连接管理,而是建立在ADO.NET的IDbConnection之上。要让Dapper操作MySQL,核心工作是选好MySQL的ADO.NET驱动,并正确建立连接对象。目前社区主流方案是使用MySqlConnector这个纯托管实现,它比官方的MySql.Data在性能和跨平台支持上更优。

Dapper怎么连接MySQL数据库?Dapper for MySQL配置方法详解

一、引入必要的NuGet包

在项目中,我们需要安装两个包:Dapper和MySqlConnector。Dapper提供扩展方法如Query、Execute;MySqlConnector提供MySqlConnection实现。打开包管理器控制台,执行以下命令:

// 使用NuGet命令行安装
// Install-Package Dapper
// Install-Package MySqlConnector

如果你使用SDK风格的项目文件,也可以直接编辑csproj,添加如下项。注意版本号可按实际情况调整,但建议Dapper使用2.x以上,MySqlConnector使用2.x以上以获得更好的异步支持。

<ItemGroup>
  <PackageReference Include="Dapper" Version="2.1.35" />
  <PackageReference Include="MySqlConnector" Version="2.3.5" />
</ItemGroup>

选择MySqlConnector而不是MySql.Data,是因为前者在连接池处理、取消令牌支持以及Linux环境下的稳定性表现更好。很多部署到Docker的.NET程序若用旧驱动,会出现SSL握手失败,而MySqlConnector默认配置更友好。

二、编写连接字符串与工厂方法

MySQL连接字符串需要包含服务器地址、库名、用户、密码以及字符集等。一个典型的连接串如下,其中AllowUserVariables允许我们在SQL中使用自定义变量,对于Dapper的动态参数很有用。

using MySqlConnector;

public static class DbFactory
{
    private const string ConnStr =
        "Server=127.0.0.1;Port=3306;Database=testdb;User=root;Password=123456;" +
        "Charset=utf8mb4;AllowUserVariables=true;Pooling=true;MinimumPoolSize=1;MaximumPoolSize=50;";

    public static MySqlConnection OpenConnection()
    {
        var conn = new MySqlConnection(ConnStr);
        conn.Open();
        return conn;
    }
}

上面的工厂方法返回已打开的MySqlConnection。在Dapper操作中,推荐用using块确保连接释放回池。Pooling=true开启连接池,能避免频繁建立TCP连接的开销。如果应用是Web服务,最大池大小应根据并发量调整,一般50到100之间。

需要注意,Charset设置为utf8mb4才能完整支持表情符与特殊汉字。若只用utf8,在MySQL服务端实际是三字节,插入四字节字符会报错。这也是很多新手配置Dapper for MySQL时的隐性坑。

三、使用Dapper执行查询与写入

拿到连接后,即可调用Dapper的扩展方法。下面示例演示参数化查询,避免SQL注入。Dapper会自动将匿名对象属性映射为@参数。

using Dapper;
using System.Linq;

public class UserRepo
{
    public User GetById(int id)
    {
        using var conn = DbFactory.OpenConnection();
        var sql = "SELECT id,name,age FROM users WHERE id = @Id";
        return conn.QueryFirstOrDefault<User>(sql, new { Id = id });
    }

    public int AddUser(User u)
    {
        using var conn = DbFactory.OpenConnection();
        var sql = "INSERT INTO users(name,age) VALUES(@Name,@Age); SELECT LAST_INSERT_ID();";
        return conn.ExecuteScalar<int>(sql, u);
    }
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

在上面的代码中,QueryFirstOrDefault方法执行查询并映射为User对象,若没有结果返回null。ExecuteScalar用于插入后取回自增主键,比先插入再查max(id)安全且高效。Dapper默认将列名按大小写不敏感匹配属性名,因此数据库用下划线命名时,可借助别名或自定义映射。

写入操作中务必通过参数对象传值,不要拼接字符串。Dapper的参数化在MySqlConnector底层会转为服务端预编译语句,既安全又减少解析成本。对于批量插入,可使用Execute对IEnumerable展开,但超大数据量建议用MySqlBulkCopy扩展。

四、常见配置错误与排查

第一类问题是连接未释放。若每次new MySqlConnection但不using或不Close,连接池会耗尽,报错Too many connections。务必将连接放在using中,或依赖DI容器作用域生命周期。

现象可能原因解决办法
无法连接 Authentication method unknownMySQL 8默认caching_sha2_password,旧驱动不支持换MySqlConnector或服务端改mysql_native_password
中文乱码连接串Charset不对或表字符集不一致统一使用utf8mb4
查询超时池满或SQL无索引调大MaximumPoolSize,加索引

第二类是事务使用不当。Dapper本身不管理事务,需要手动在连接上BeginTransaction并传给Dapper方法。如下片段展示如何保证两步写原子性。

using var conn = DbFactory.OpenConnection();
using var tx = conn.BeginTransaction();
try
{
    conn.Execute("UPDATE accounts SET balance=balance-@Amt WHERE id=@Id",
        new { Amt = 100, Id = 1 }, tx);
    conn.Execute("UPDATE accounts SET balance=balance+@Amt WHERE id=@Id",
        new { Amt = 100, Id = 2 }, tx);
    tx.Commit();
}
catch
{
    tx.Rollback();
    throw;
}

通过事务对象传入,Dapper会在同一连接同一事务内执行命令。这种方式比依赖外部ORM的事务更透明,也契合Dapper保持简单的设计哲学。只要把握住驱动选择、连接串、释放与事务四点,Dapper for MySQL的配置就基本无碍。

DapperMySQLMySqlConnector修改时间:2026-08-10 01:30:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。