NewLife.MySql 架构

March 1, 2026 · View on GitHub

1. 架构概览

NewLife.MySql 采用四层架构,自上而下分为应用层、ADO.NET 标准接口层、连接池层、协议+网络层。核心协议实现集中在 SqlClient 单一类中(约 900 行),整体代码量约 3000 行,极简设计。

┌─────────────────────────────────────────────┐
│              应用层 (Application)             │
│  DAL / XCode / 直接使用 ADO.NET 接口          │
└─────────────────────┬───────────────────────┘

┌─────────────────────▼───────────────────────┐
│            ADO.NET 标准接口层                  │
│  MySqlConnection  MySqlCommand               │
│  MySqlDataReader  MySqlTransaction           │
│  MySqlParameter   MySqlParameterCollection   │
│  MySqlClientFactory  MySqlDataAdapter        │
│  MySqlBatch / MySqlBatchCommand (.NET 6+)    │
└─────────────────────┬───────────────────────┘

┌─────────────────────▼───────────────────────┐
│              连接池层 (Pool)                   │
│  MySqlPoolManager  MySqlPool                 │
│  按连接字符串分池,复用 SqlClient 连接          │
└─────────────────────┬───────────────────────┘

┌─────────────────────▼───────────────────────┐
│            协议层 (Protocol)                   │
│  SqlClient         Authentication            │
│  SchemaProvider    WelcomeMessage             │
│  Response          MySqlColumn               │
│  BinaryHelper      ClientFlags               │
└─────────────────────┬───────────────────────┘

┌─────────────────────▼───────────────────────┐
│            网络层 (Network)                    │
│  TcpClient + NetworkStream                   │
│  SslStream (可选 TLS 加密)                    │
└─────────────────────────────────────────────┘

核心类关系

ADO.NET 标准接口

类名基类职责
MySqlClientFactoryDbProviderFactory工厂类,创建连接/命令/参数等对象,管理连接池
MySqlConnectionDbConnection数据库连接,管理生命周期和状态
MySqlCommandDbCommandSQL 命令执行,参数化查询,存储过程调用
MySqlDataReaderDbDataReader结果集读取,逐行读取数据,多结果集遍历
MySqlTransactionDbTransaction事务管理,提交/回滚,自动回滚
MySqlParameterDbParameter查询参数,支持输入/输出方向
MySqlParameterCollectionDbParameterCollection参数集合
MySqlConnectionStringBuilderDbConnectionStringBuilder连接字符串解析
MySqlDataAdapterDbDataAdapter数据适配器,DataSet/DataTable 填充和更新
MySqlBatch (.NET 6+)DbBatchADO.NET 标准批量命令
MySqlBatchCommand (.NET 6+)DbBatchCommand批量命令中的单条命令

协议层

类名职责
SqlClient核心协议实现,管理 TCP 连接、收发数据包、协议解析
AuthenticationMySQL 认证流程(mysql_native_password / caching_sha2_password)
Response响应包封装,判断 OK/Error/EOF
WelcomeMessage握手欢迎消息解析
SchemaProviderSchema 信息查询(数据库/表/列/索引)
MySqlColumn结果集列元数据

辅助类

类名职责
BinaryHelperMySQL 协议二进制读写扩展方法
MySqlDbTypeMySQL 数据类型枚举
ClientFlags客户端能力标志位
ServerStatus / ServerStatusFlags服务器状态标志位
DbCmdMySQL 命令类型枚举
MySqlExceptionMySQL 异常类
QueryResult / RowResult查询结果和行读取结果

协议层架构

SqlClient(协议层核心,单一职责)
├── OpenAsync()     → TCP 连接 + 握手 + 认证
├── SendPacketAsync()  → 帧封装 + 发送
├── ReadPacketAsync()  → 帧解析 + 超时控制
├── SendQueryAsync()   → COM_QUERY 文本协议
├── PrepareStatementAsync()  → COM_STMT_PREPARE
├── ExecuteStatementAsync()  → COM_STMT_EXECUTE 二进制协议
├── ExecuteStatementPipelineAsync()  → 管道化/串行批量执行
│   ├── ExecutePipelineCoreAsync()  → 真管道化(批发批收)
│   └── 串行循环 → 逐条发送+读取
├── BuildExecutePacket()  → 构建 EXECUTE 包(与发送解耦)
└── GetResult() / NextRowAsync() / NextBinaryRowAsync()  → 响应解析

2. 数据模型

2.1 MySQL 协议数据模型

协议包格式

+-------------------+-------+-----------+
|  payload_length   |  seq  |  payload  |
|     3 bytes       | 1byte | N bytes   |
+-------------------+-------+-----------+
  • payload_length:3 字节小端序,最大 16MB(0xFFFFFF)
  • seq:1 字节序列号,每次请求重置为 0,每个包递增
  • 超过 16MB 的数据包自动拆分为多个 16MB 帧

数据类型映射

MySQL 类型MySqlDbType.NET 类型
TINYINTByteSByte
SMALLINTInt16Int16
MEDIUMINTInt24Int32
INTInt32Int32
BIGINTInt64Int64
FLOATFloatSingle
DOUBLEDoubleDouble
DECIMAL / NUMERICNewDecimalDecimal
VARCHAR / CHARVarChar / StringString
TEXT (各种)TextString
BLOB (各种)BlobByte[]
DATETIME / TIMESTAMPDateTime / TimestampDateTime
DATE / TIMEDate / TimeDateTime
BITBitBoolean
JSONJsonString
ENUMEnumString

参数化查询类型映射

.NET 类型SQL 字面量
String'hello'(自动转义)
数字类型42
Boolean1 / 0
DateTime / DateTimeOffset'2025-07-01 12:30:00'
Byte[]X'CAFE'
Guid'01234567-89ab-cdef-...'
Enum转为数字
Single / Double往返格式(R
Decimal原样输出
null / DBNull.ValueNULL

2.2 连接字符串模型

参数别名默认值说明
ServerDataSource, Data Source-服务器地址
Port-3306端口号
Database--数据库名
UserIDUid, User Id, User-用户名
PasswordPass, Pwd-密码
ConnectionTimeoutConnection Timeout15连接超时(秒)
CommandTimeoutDefault Command Timeout30命令超时(秒)
SslModeSsl ModeNoneSSL 模式
UseServerPrepareUse Server Preparefalse全局服务端预编译开关
PipelinePipeliningfalse管道化执行开关

2.3 MySQL 版本兼容矩阵

特性MySQL 5.5MySQL 5.6MySQL 5.7MySQL 8.0MySQL 8.4MySQL 9.0
默认认证native_passwordnative_passwordnative_passwordcaching_sha2caching_sha2caching_sha2
COM_RESET_CONNECTION
JSON 类型
TLS 1.3✓ (8.0.16+)
mysql_native_password默认默认默认可用废弃已移除

2.4 兼容数据库检测

数据库支持状态检测规则说明
MySQL✅ 完整支持标准版本字符串(如 8.0.265.5 ~ 9.0 全版本
OceanBase✅ 完整支持版本含 OceanBase(如 5.7.25-OceanBase-v4.0.0基于版本字符串自动识别
TiDB✅ 完整支持版本含 TiDB(如 5.7.25-TiDB-v6.5.2基于版本字符串自动识别
MariaDB✅ 基础支持-缺少 ed25519 认证

3. 接口设计

3.1 ADO.NET 标准接口

接口方法签名入参出参说明
MySqlConnectionOpen / OpenAsyncvoid Open() / Task OpenAsync()--从连接池获取连接
MySqlConnectionClose / CloseAsyncvoid Close() / Task CloseAsync()--归还连接到连接池
MySqlConnectionChangeDatabasevoid ChangeDatabase(String)数据库名-通过 Close+Reopen 切换
MySqlConnectionGetSchemaDataTable GetSchema(String)集合名DataTable查询元数据
MySqlConnectionBeginTransactionMySqlTransaction BeginTransaction(IsolationLevel)隔离级别事务对象开始事务
MySqlCommandExecuteReaderDbDataReader ExecuteReader()-DataReader执行查询返回结果集
MySqlCommandExecuteScalarObject ExecuteScalar()-第一行第一列执行查询返回单值
MySqlCommandExecuteNonQueryInt32 ExecuteNonQuery()-影响行数执行 DML
MySqlCommandPreparevoid Prepare()--服务端预编译

3.2 批量操作扩展接口

接口方法签名入参出参说明
MySqlCommandExecuteBatchInt32 ExecuteBatch(IList<IDictionary<String, Object?>>)字典参数集累计影响行数字典参数集批量执行
MySqlCommandExecuteBatchAsyncTask<Int32> ExecuteBatchAsync(...)字典参数集累计影响行数异步字典参数集批量
MySqlCommandExecuteArrayBatchInt32 ExecuteArrayBatch(Int32)执行次数累计影响行数数组绑定批量执行
MySqlCommandExecuteArrayBatchAsyncTask<Int32> ExecuteArrayBatchAsync(...)执行次数累计影响行数异步数组绑定批量

3.3 协议层内部接口

接口方法签名说明
SqlClientOpenAsyncTask OpenAsync(MySqlConnectionStringBuilder, CancellationToken)TCP 连接 + 握手 + 认证
SqlClientSendQueryAsyncTask<QueryResult> SendQueryAsync(String, CancellationToken)COM_QUERY 文本协议
SqlClientPrepareStatementAsyncTask<Int32> PrepareStatementAsync(String, CancellationToken)COM_STMT_PREPARE
SqlClientExecuteStatementAsyncTask<QueryResult> ExecuteStatementAsync(Int32, MySqlParameterCollection, CancellationToken)COM_STMT_EXECUTE
SqlClientExecuteStatementPipelineAsyncTask<Int32> ExecuteStatementPipelineAsync(Int32, IList<MySqlParameterCollection>, Boolean, CancellationToken)管道化/串行批量执行
SqlClientBuildExecutePacketByte[] BuildExecutePacket(Int32, MySqlParameterCollection)构建 EXECUTE 包(与发送解耦)
SqlClientSetDatabaseAsyncTask SetDatabaseAsync(String, CancellationToken)COM_INIT_DB 切换数据库

4. 技术选型

领域选型理由
基础框架NewLife.Core同为 NewLife 团队出品,提供 ObjectPool / ArrayPool / Pool.StringBuilder 等基础设施
网络通信TcpClient + NetworkStream标准 .NET TCP 通信,全框架兼容
TLS 加密SslStream标准 .NET SSL/TLS 实现,条件编译适配 TLS 1.3
内存管理ArrayPool + OwnerPacket零额外分配,减少 GC 压力
连接池ObjectPool<SqlClient>NewLife.Core 提供的轻量级对象池
字符串构建Pool.StringBuilderNewLife.Core 提供的池化 StringBuilder
异步模型async/await + Task全链路真异步,兼容 net45(通过 Microsoft.Bcl.Async)
多目标框架net45 / net461 / netstandard2.0 / netstandard2.1 / net6.0 / net10.0覆盖最广的框架兼容性
开源协议MIT商用友好,无 GPL 风险

5. 关键设计决策

决策点方案备选方案选择理由
参数化查询实现客户端参数替换服务端预编译(COM_STMT_PREPARE)减少网络往返,与 MySql.Data 行为一致,兼容性好;预编译作为可选(UseServerPrepare)
ChangeDatabase 实现Close + ReopenCOM_INIT_DB 命令简单,连接池映射正确,无状态污染风险;COM_INIT_DB 作为低级 API 可选
批量操作协议COM_STMT_PREPARE + COM_STMT_EXECUTECOM_QUERY 文本协议拼接二进制协议更高效,参数类型精确,无 SQL 注入风险
管道化执行包构建与发送解耦(BuildExecutePacket + 延迟 Flush)逐条发送等响应批量发送减少网络往返,TCP Nagle 合并小包,大数据场景 4~8× 加速
管道化错误处理失败时继续读取后续响应,最后抛出第一个错误遇错立即中断保持连接状态干净,避免残留数据污染后续操作
存储过程实现SET + CALL + SELECT 多语句逐步发送独立命令利用多语句能力一次网络往返完成,减少延迟
认证架构内置 Authentication 类插件系统仅需支持两种认证方式,插件系统过度设计;极简实现约 200 行
连接池实现继承 ObjectPool<SqlClient>自定义连接池复用 NewLife.Core 成熟实现,减少代码量;服务器变量缓存 10 分钟额外优化
IO 模型纯 async/await + TaskValueTask / PipeReaderTask 全框架兼容(含 net45),轻量级定位无需 PipeReader 复杂度
EF Core 支持方式独立包 NewLife.MySql.EntityFrameworkCore内置保持核心包轻量,EF Core 用户按需引用

6. 任务分解

项目已基本开发完成,以下为历史任务分解记录。

任务 T001:实现 MySQL 协议握手与连接

  • 对应功能:F001
  • 产出:SqlClient.OpenAsync、WelcomeMessage、BinaryHelper
  • 验收:TCP 连接建立,欢迎包解析成功

任务 T002:实现 mysql_native_password 认证

  • 对应功能:F002
  • 产出:Authentication.AuthenticateAsync、SHA1 双重哈希
  • 验收:MySQL 5.x/8.0 native_password 认证通过

任务 T003:实现 caching_sha2_password 认证

  • 对应功能:F003
  • 产出:Authentication 扩展 SHA256 + RSA 全量认证
  • 验收:MySQL 8.0+ 默认认证通过,含 RSA 公钥请求

任务 T004:实现连接池

  • 对应功能:F004
  • 产出:MySqlPoolManager、MySqlPool
  • 验收:按连接字符串分池,空闲回收,健康检查

任务 T005:实现连接字符串解析

  • 对应功能:F005
  • 产出:MySqlConnectionStringBuilder
  • 验收:全部参数别名正确解析

任务 T006:实现 SSL/TLS 加密

  • 对应功能:F006
  • 产出:SqlClient SSL 升级逻辑
  • 验收:SslMode=Preferred/Required 正常工作

任务 T007:实现 ExecuteReader 与 DataReader

  • 对应功能:F007, F012
  • 产出:MySqlCommand.ExecuteReaderAsync、MySqlDataReader
  • 验收:结果集读取、多结果集遍历、类型映射

任务 T008:实现 ExecuteScalar 与 ExecuteNonQuery

  • 对应功能:F008, F009
  • 产出:MySqlCommand.ExecuteScalarAsync、ExecuteNonQueryAsync
  • 验收:单值查询、DML 影响行数

任务 T009:实现参数化查询

  • 对应功能:F010
  • 产出:MySqlParameter、MySqlParameterCollection、参数替换逻辑
  • 验收:@参数名替换,转义防注入

任务 T010:实现预编译语句

  • 对应功能:F011
  • 产出:SqlClient.PrepareStatementAsync、ExecuteStatementAsync
  • 验收:COM_STMT_PREPARE/EXECUTE 二进制协议

任务 T011:实现事务支持

  • 对应功能:F013
  • 产出:MySqlTransaction
  • 验收:四种隔离级别,自动回滚

任务 T012:实现存储过程调用

  • 对应功能:F014
  • 产出:MySqlCommand 存储过程分支
  • 验收:IN/OUT 参数,多语句执行

任务 T013:实现字典参数集批量操作

  • 对应功能:F015
  • 产出:MySqlCommand.ExecuteBatchAsync
  • 验收:自动 Prepare + Execute × N

任务 T014:实现数组绑定批量操作

  • 对应功能:F016
  • 产出:MySqlCommand.ExecuteArrayBatchAsync
  • 验收:数组参数按索引提取执行

任务 T015:实现管道化执行

  • 对应功能:F017
  • 产出:SqlClient.ExecuteStatementPipelineAsync、ExecutePipelineCoreAsync、BuildExecutePacket
  • 验收:Pipeline=true 批发批收,加速比 ≥ 4×

任务 T016:实现 Schema 查询

  • 对应功能:F018
  • 产出:SchemaProvider
  • 验收:Databases/Tables/Columns/Indexes 查询

任务 T017:实现 MySqlClientFactory 与 XCode 集成

  • 对应功能:F019
  • 产出:MySqlClientFactory
  • 验收:XCode DAL 自动识别驱动

任务 T018:实现 DbBatch API

  • 对应功能:F020
  • 产出:MySqlBatch、MySqlBatchCommand
  • 验收:.NET 6+ 标准批量 API

任务 T019:实现 DataAdapter

  • 对应功能:F021
  • 产出:MySqlDataAdapter
  • 验收:Fill DataTable

任务 T020:实现兼容数据库检测

  • 对应功能:F022
  • 产出:DatabaseType 枚举、版本字符串检测
  • 验收:OceanBase/TiDB 自动识别

任务 T021:实现 ChangeDatabase

  • 对应功能:F023
  • 产出:MySqlConnection.ChangeDatabase、SqlClient.SetDatabaseAsync
  • 验收:Close+Reopen 切换,连接池映射正确

任务 T022:实现 EF Core Provider

  • 对应功能:F024
  • 产出:NewLife.MySql.EntityFrameworkCore 独立项目
  • 验收:类型映射、查询翻译、迁移支持

7. 风险与缓解

风险影响缓解措施
MySQL 9.0 移除 mysql_native_password仅支持 caching_sha2_password 的环境下老客户端无法连接已实现 caching_sha2_password 认证,含 RSA 全量认证和 Auth Switch
管道化执行中途失败连接状态可能不一致,后续操作异常失败时继续读取后续响应保持连接干净,最后抛出第一个错误
大包超过 max_allowed_packet多行 VALUES 或大批量参数替换可能超限客户端参数替换模式需注意 SQL 长度;预编译+二进制协议不受影响
net45 异步兼容性.NET Framework 4.5 异步支持有限依赖 Microsoft.Bcl.Async,条件编译适配
连接池状态污染使用 SetDatabaseAsync 后归还连接可能污染池ChangeDatabase 默认使用 Close+Reopen 避免污染;SetDatabaseAsync 仅作为低级 API
EF Core 版本演进EF Core 新版本可能引入 breaking change独立包隔离,不影响核心驱动

附录 A:协议交互流程

A.1 连接建立

Client                          Server
  │                               │
  │◄──── Welcome Packet ──────────│  服务器发送欢迎消息(协议版本/能力/种子)
  │                               │
  │  [可选] SSL Request ─────────►│  如果 SslMode != None
  │◄──── TLS Handshake ──────────►│  升级为加密连接
  │                               │
  │  Auth Response ──────────────►│  发送认证信息(用户名/加密密码/数据库)
  │◄──── OK / Auth Switch ───────│  认证结果(可能需要切换认证方式)
  │                               │
  │  [可选] RSA 公钥请求 ─────────►│  caching_sha2_password 全量认证
  │◄──── RSA 公钥 ───────────────│
  │  加密密码 ───────────────────►│
  │◄──── OK ─────────────────────│
  │                               │
  │  SHOW VARIABLES ─────────────►│  获取服务器变量配置
  │◄──── Result Set ─────────────│  max_allowed_packet / charset 等
  │                               │

A.2 查询执行

Client                          Server
  │                               │
  │  COM_QUERY(SQL) ─────────────►│  发送 SQL 查询
  │                               │
  │  [查询结果]                     │
  │◄──── Column Count ───────────│  列数量
  │◄──── Column Definitions ─────│  列定义 × N
  │◄──── EOF ────────────────────│  列定义结束
  │◄──── Row Data ───────────────│  行数据 × M(文本协议,每列 length-encoded string)
  │◄──── EOF ────────────────────│  结果集结束(状态标志含 MORE_RESULTS 标志)
  │                               │
  │  [非查询结果]                   │
  │◄──── OK Packet ──────────────│  affected_rows + last_insert_id + status_flags
  │                               │

A.3 多语句执行

Client                          Server
  │                               │
  │  COM_QUERY(SQL1;SQL2;SQL3) ──►│  发送多条 SQL(分号分隔)
  │                               │
  │◄──── Result1 (OK/ResultSet) ─│  第一条 SQL 结果,status_flags 含 MORE_RESULTS
  │◄──── Result2 (OK/ResultSet) ─│  第二条 SQL 结果
  │◄──── Result3 (OK/ResultSet) ─│  第三条 SQL 结果,status_flags 不含 MORE_RESULTS
  │                               │

A.4 存储过程调用

Client                          Server
  │                               │
  │  CALL proc(@p1, @p2) ───────►│  调用存储过程
  │                               │
  │◄──── ResultSet(s) ───────────│  过程中的 SELECT 结果(0~N 个)
  │◄──── OK Packet ──────────────│  最终状态,status_flags 含 MORE_RESULTS
  │◄──── OK Packet ──────────────│  CALL 语句本身的 OK 包
  │                               │
  │  [读取输出参数]                  │
  │  SELECT @p2 ─────────────────►│  读取 OUT 参数值
  │◄──── ResultSet ──────────────│
  │                               │

A.5 事务流程

Client                          Server
  │                               │
  │  SET TRANSACTION ... ────────►│  设置隔离级别
  │◄──── OK ─────────────────────│
  │                               │
  │  BEGIN ──────────────────────►│  开始事务
  │◄──── OK ─────────────────────│
  │                               │
  │  INSERT/UPDATE/DELETE ───────►│  业务 SQL
  │◄──── OK ─────────────────────│
  │                               │
  │  COMMIT / ROLLBACK ──────────►│  提交或回滚
  │◄──── OK ─────────────────────│
  │                               │

A.6 管道化批量执行

串行模式(默认)

$ \text{Client} \text{Server} │ │ │ \text{COM\_STMT\_EXECUTE}(1) ───────►│ 发送第 1 组参数 │◄──── \text{OK} ─────────────────────│ 接收第 1 个响应 │ \text{COM\_STMT\_EXECUTE}(2) ───────►│ 发送第 2 组参数 │◄──── \text{OK} ─────────────────────│ 接收第 2 个响应 │ \text{COM\_STMT\_EXECUTE}(\text{N}) ───────►│ 发送第 \text{N} 组参数 │◄──── \text{OK} ─────────────────────│ 接收第 \text{N} 个响应 │ │ │ 耗时 ≈ \text{N} \times (发送延迟 + 处理时间 + 接收延迟) $

管道化模式(Pipeline=true)

Client                          Server
  │                               │
  │  ── Phase 1: 批量发送 ──       │
  │  COM_STMT_EXECUTE(1) ───────►│  连续发送,不等响应
  │  COM_STMT_EXECUTE(2) ───────►│  TCP 协议栈合并小包
  │  COM_STMT_EXECUTE(3) ───────►│
  │  ...                          │
  │  COM_STMT_EXECUTE(N) ───────►│  最后一个包 Flush
  │                               │
  │  ── Phase 2: 批量读取 ──       │  服务器按顺序处理并返回
  │◄──── OK(1) ──────────────────│  逐个读取 OK 包
  │◄──── OK(2) ──────────────────│  累加 affected_rows
  │◄──── OK(3) ──────────────────│
  │  ...                          │
  │◄──── OK(N) ──────────────────│
  │                               │
  │  耗时 ≈ 批量发送时间 + N × 处理时间 + 批量接收时间

附录 B:关键实现细节

B.1 连接池设计

MySqlClientFactory
  └── MySqlPoolManager(单例,管理所有连接池)
        └── MySqlPool(按连接字符串分组)
              ├── SqlClient #1 (active)
              ├── SqlClient #2 (idle)
              └── SqlClient #N ...
  • 继承 NewLife.Collections.ObjectPool<SqlClient>
  • 按连接字符串哈希分池,相同连接字符串共用同一个池
  • 默认最小连接数 10,最大 100000
  • 空闲超时 30 秒,全空闲超时 300 秒
  • 获取连接时验证可用性(Reset 检查 + Active 状态检查)
  • 归还时连接保持打开状态以便复用
  • 服务器变量缓存 10 分钟,减少 SHOW VARIABLES 查询

ChangeDatabase 连接池映射

MySqlPoolManager 使用完整连接字符串作为 Key。ChangeDatabase 通过 Close+Reopen 实现:

步骤操作连接字符串连接池
1Open()...Database=db1...Pool1
2ChangeDatabase("db2")
3Close()归还到 Pool1
4↳ 改 Setting.Database...Database=db2...-
5Open()从 Pool2 获取

每个连接池中的连接保持一致的数据库状态,避免污染。

B.2 认证实现

认证方式引入版本默认版本实现要点
mysql_native_passwordMySQL 4.15.x~5.7SHA1 双重哈希,20 字节响应
caching_sha2_passwordMySQL 8.08.0+SHA256 哈希,首次需 RSA/TLS 传输密码

认证流程:服务器欢迎包 → 客户端计算密码哈希 → 发送认证响应 → 处理 Auth Switch(0xFE)→ caching_sha2 缓存未命中时 RSA 公钥加密传输。

B.3 存储过程实现

  1. CommandText 转换为 CALL proc_name(@p1, @p2, ...) 语句
  2. 输入参数通过 SET @p1=value 预先设置为 MySQL 用户变量
  3. 输出参数通过 SELECT @p2 在 CALL 执行后读取
  4. 利用多语句能力一次发送 SET...;CALL...;SELECT...

B.4 批量操作实现流程

ExecuteBatch / ExecuteArrayBatch

  ├── 自动 Prepare(若未预编译)
  │     └── ConvertToPositionalParameters → PrepareStatementAsync

  ├── 提取每组参数 → MySqlParameterCollection 列表
  │     ├── ExecuteBatch: 从字典提取
  │     └── ExecuteArrayBatch: 从数组中按索引提取

  ├── 调用 ExecuteStatementPipelineAsync
  │     ├── Pipeline=true:  BuildExecutePacket×N → SendPacket(flush:false)×N → Flush → ReadPacket×N
  │     └── Pipeline=false: (ExecuteStatement → ReadPacket) × N

  └── 自动 Unprepare(若本次自动预编译的)

B.5 DataReader 状态管理

ExecuteReaderAsync 返回时:
┌────────────────────────────────┐
│ Reader 定位在第一个结果         │
│ _FieldCount = 0 或 > 0         │
│ _hasMoreResults = true/false   │
│ _allRowsConsumed = true        │
└────────────────────────────────┘

    调用 ReadAsync()

┌────────────────────────────────┐
│ 如果 FieldCount > 0             │
│   读取一行数据,填充 _Values    │
│   _allRowsConsumed = false     │
└────────────────────────────────┘

    调用 NextResultAsync()

┌────────────────────────────────┐
│ 消费当前结果集的剩余行          │
│ 读取下一个结果                  │
│ 更新 _FieldCount                │
│ 累加 _RecordsAffected           │
│ 更新 _hasMoreResults            │
└────────────────────────────────┘

B.6 多目标框架

框架说明
net45.NET Framework 4.5
net461.NET Framework 4.6.1
netstandard2.0.NET Standard 2.0
netstandard2.1.NET Standard 2.1(支持异步 Dispose、CloseAsync)
net6.0.NET 6(额外支持 DbBatch API)
net10.0.NET 10(最新框架,最优性能)

条件编译符号:NETFRAMEWORKNET45NETSTANDARD2_1_OR_GREATERNET5_0_OR_GREATERNET6_0_OR_GREATER

附录 C:与主流驱动对比

C.1 总体架构对比

架构维度NewLife.MySqlMySqlConnectorMySql.Data (Oracle)
架构层次4 层5 层(含中间件层)4 层
协议实现单一 SqlClientMySqlSession + MySqlProtocolSerializer 分离NativeDriver 单体
IO 模型async/awaitasync/await + ValueTask同步为主
内存管理ArrayPool + OwnerPacketArrayPool + SequenceReader传统 byte[] 分配
连接池ObjectPool<SqlClient>自定义 ConnectionPool自定义连接池
代码行数~3000 行~30000 行~50000 行

C.2 批量操作对比(核心竞争力)

批量方案NewLife.MySqlMySqlConnectorMySql.Data
字典参数集批量ExecuteBatch
数组绑定批量ExecuteArrayBatch
管道化执行Pipeline=true
DbBatch✅ (.NET 6+)✅ (.NET 6+)
BulkCopy

C.3 性能数据

管道化+事务 vs 逐行基线(.NET 10 + MySQL 8.0.26 本机):

场景逐行基线管道化+事务加速比
1,000 行 INSERT437ms54ms8.1×
10,000 行 INSERT3,150ms680ms4.6×
10,000 行 UPDATE3,469ms757ms4.6×
10,000 行 DELETE3,351ms673ms5.0×

三驱动对比(10,000 行批量操作):

操作NewLife Pipeline(tx)MySql.Data Batch(tx)MySqlConnector Batch(tx)NewLife 加速比
INSERT899ms1,927ms1,906ms2.1×
UPDATE710ms2,265ms2,041ms2.9×
DELETE661ms1,961ms1,767ms2.7×

详细数据参见 性能测试报告

C.4 适用场景

场景推荐驱动理由
大数据批量 DMLNewLife.MySql管道化 + 数组绑定,性能最优
国产化/信创NewLife.MySql纯国产、MIT、零第三方依赖
XCode ORM 项目NewLife.MySql原生集成,无缝对接
轻量级微服务NewLife.MySql代码精简,启动快
EF Core 项目MySqlConnectorPomelo.EF 支持
需要 BulkCopyMySqlConnectorMySqlBulkCopy API
需要压缩协议MySqlConnector内置压缩支持