
TypeORM 的 MySQL / MariaDB / Aurora MySQL 驱动全解连接选项、列类型与源码级行为剖析【免费下载链接】typeormTypeScript JavaScript ORM for Node.js — supports PostgreSQL, MySQL, MariaDB, SQLite, SQL Server, Oracle, and more.项目地址: https://gitcode.com/GitHub_Trending/ty/typeorm本文基于 TypeORM 官方驱动文档 MySQL / MariaDB系统讲解如何在 TypeORM 中接入 MySQL、MariaDB 与 Amazon Aurora MySQL从安装底层驱动、逐项解析数据源连接选项到列类型支持、set/enum列的定义方式与 Vector 类型的适用版本并结合src/driver/mysql/下的驱动源码揭示连接池创建、版本探测、参数转义、upsert 语句生成等关键行为的真实实现帮助你在生产环境中正确配置并排查 MySQL 驱动相关问题。一、驱动安装与加载机制TypeORM 自身不内置数据库连接库MySQL 系驱动依赖社区的mysql2包。安装命令npm install mysql2从源码可以确认这一依赖关系。MysqlDriver构造时会调用loadDependencies()加载逻辑位于 MysqlDriver.tsprotected loadDependencies(): void { try { this.mysql this.options.driver ?? PlatformTools.load(mysql2) } catch (e) { throw new DriverPackageNotInstalledError(Mysql, mysql2) } }两个要点默认通过PlatformTools.load(mysql2)加载mysql2加载失败则抛出DriverPackageNotInstalledError提示你安装该包——这就是必须先npm install mysql2的底层原因数据源选项中的driver字段允许你注入自定义的驱动对象见 MysqlDataSourceOptions.ts 中driver的注释This defaults to require(mysql2)便于使用自行封装的客户端。二、三种数据源类型mysql、mariadb、aurora-mysql官方文档指出可以使用mysql、mariadb、aurora-mysql三种数据源类型分别连接对应的数据库。在源码层面MysqlDataSourceOptions 接口将type限定为mysql | mariadb这两个类型共享同一套 MySQL 驱动实现aurora-mysql是独立的驱动实现位于 AuroraMysqlDriver同样基于 MySQL 协议但针对 Amazon Aurora 做了适配。通用的数据源选项如entities、synchronize、migrations等请参考 Data Source Options 文档。三、连接选项全解析以下是 MySQL 系驱动支持的全部数据源选项完整继承自官方文档 docs/docs/drivers/mysql.md并与 MysqlDataSourceOptions 接口逐一对照选项说明默认值url连接 URL。注意其他显式配置的数据源选项会覆盖从 URL 中解析出的参数—host数据库主机—port数据库端口MySQL 默认3306username数据库用户名—password数据库密码—database数据库名—socketPath数据库 socket 路径本机 Unix socket 连接—poolSize每个连接池中最大的客户端数量—charset/collation连接的字符集/排序规则。若指定 SQL 级字符集如utf8mb4则使用该字符集的默认排序规则接口注释为UTF8_GENERAL_CItimezoneMySQL 服务器上配置时区用于服务端日期时间与 JavaScriptDate对象互转。可取local、Z或HH:MM/-HH:MM偏移localconnectTimeout初始连接 MySQL 服务器前的超时毫秒数10000acquireTimeout从连接池获取连接的超时毫秒数与connectTimeoutTCP 连接超时职责不同10000insecureAuth是否允许连接使用旧不安全认证方式的 MySQL 实例falsesupportBigNumbers处理BIGINT与DECIMAL大数列时应启用的选项true源码实际生效值bigNumberStrings同时启用supportBigNumbers与bigNumberStrings时大数强制以字符串返回仅启用前者时仅在超出[-2^53, 2^53]范围时返回字符串否则返回Number若supportBigNumbers关闭则本选项被忽略true源码实际生效值dateStrings强制日期类型TIMESTAMP、DATETIME、DATE以字符串而非Date对象返回。可为布尔值或类型名数组falsedebug向 stdout 打印协议细节。可为布尔值或需要打印的包类型名数组falsetrace出错时生成包含库入口调用栈的长堆栈对多数调用有轻微性能开销truemultipleStatements是否允许单条查询执行多条 MySQL 语句可能扩大 SQL 注入面谨慎使用falselegacySpatialSupport是否使用旧版空间函数如GeomFromText、AsText这些函数已在 MySQL 8.0 中被标准函数ST_GeomFromText、ST_AsText取代falseflags除默认外的连接标志列表也支持黑名单式禁用默认标志—sslSSL 参数对象或 SSL profile 名称字符串—enableQueryTimeout当设置了maxQueryExecutionTime时除产生告警日志外还将其作为查询执行超时使用—以上选项之外任何额外选项都可以放入extra对象会被原样透传给底层客户端库。这一点在源码中可以直接印证createConnectionOptions()MysqlDriver.ts#L1159-L1201在拼装连接参数时最后合并了options.extra ?? {}return Object.assign( {}, { charset: options.charset, timezone: options.timezone, connectTimeout: options.connectTimeout, insecureAuth: options.insecureAuth, supportBigNumbers: options.supportBigNumbers ?? true, bigNumberStrings: options.bigNumberStrings ?? true, dateStrings: options.dateStrings, debug: options.debug, trace: options.trace, multipleStatements: options.multipleStatements, flags: options.flags, stringifyObjects: true, }, { host: credentials.host, user: credentials.username, password: credentials.password, database: credentials.database, port: credentials.port, ssl: options.ssl, socketPath: credentials.socketPath, connectionLimit: credentials.poolSize ?? options.poolSize, }, options.acquireTimeout undefined ? {} : { acquireTimeout: options.acquireTimeout }, options.extra ?? {}, )从这段实现可以确认几个文档未明示的事实supportBigNumbers与bigNumberStrings的运行时默认值均为true?? true与文档标注的默认值一致。需要注意 MysqlDataSourceOptions 接口上的 JSDoc 注释写的是Default: false那是底层库的原始默认值TypeORM 在组装连接参数时主动改成了true。因此 MySQL 系驱动下读取BIGINT/DECIMAL大数会得到字符串这是有意的精度保护策略poolSize最终映射为mysql2的connectionLimit驱动还会强制加上stringifyObjects: true对象型参数会以 JSON 字符串形式传给服务器extra具有最高合并优先级可以覆盖前面所有同名参数。四、连接池与读写分离replication普通模式下MysqlDriver.connect()调用createPool()创建连接池并立刻试探性获取一次连接以尽早暴露凭据错误对应 issue #610 的历史处理见 MysqlDriver.ts#L1208-L1223// (issue #610) we make first connection to database to make sure if connection credentials are wrong // we give error before calling any other method that creates actual query runner pool.getConnection((err, connection) { if (err) return pool.end(() fail(err)) connection.release() ok(pool) })若配置了replication驱动则改用PoolCluster实现读写分离。connect()中会为每个 slave 注册SLAVE index组、为主库注册MASTER组MysqlDriver.ts#L378-L400。replication支持的字段在 MysqlDataSourceOptions 中有完整定义字段说明默认值master承载所有写操作的主库凭据必填slaves只读从库凭据数组必填canRetry连接失败时 PoolCluster 是否尝试重连trueremoveNodeErrorCounterrorCount超过该值时把节点移出 PoolCluster5restoreNodeTimeout节点重新可用的等待毫秒数设为0则节点被直接移除且永不复用0selector从库选择策略RR轮询 /RANDOM随机 /ORDER无条件取第一个可用节点—defaultModeSELECT 查询默认使用的连接池模式slave查询执行时MysqlQueryRunner按模式选择obtainMasterConnection()MASTER组或obtainSlaveConnection()SLAVE*组未开启读写分离时两者都回落到主连接池MysqlDriver.ts#L941-L992。五、版本探测与能力开关MySQL 驱动的一大特点是连接后探测数据库版本动态开启能力。connect()末尾的逻辑MysqlDriver.ts#L414-L431if (this.options.type mariadb) { if (VersionUtils.isGreaterOrEqual(this.version, 10.0.5)) { this._isReturningSqlSupported.delete true } if (VersionUtils.isGreaterOrEqual(this.version, 10.5.0)) { this._isReturningSqlSupported.insert true } if (VersionUtils.isGreaterOrEqual(this.version, 10.2.0)) { this.cteCapabilities.enabled true } if (VersionUtils.isGreaterOrEqual(this.version, 10.7.0)) { this.uuidColumnTypeSuported true } } else if (this.options.type mysql) { if (VersionUtils.isGreaterOrEqual(this.version, 8.0.0)) { this.cteCapabilities.enabled true } }据此可得到一张版本—能力对照表能力MySQLMariaDBRETURNING 语句delete不支持≥ 10.0.5RETURNING 语句insert不支持≥ 10.5.0CTE公用表表达式≥ 8.0.0≥ 10.2.0原生uuid列类型不支持回落为varchar(36)≥ 10.7.0版本探测本身由MysqlQueryRunner的getVersion()MysqlQueryRunner.ts#L3589通过向数据库发查询完成。这意味着同一份实体代码连不同版本的数据库TypeORM 生成的 SQL是否带WITH RECURSIVE、insert 是否带RETURNING会自动适配无需手工判断版本。另外两个与类型直接相关的版本敏感行为json类型在 MariaDB 10.4.3 上映射为longtextnormalizeType()中有明确分支MysqlDriver.ts#L771-L783因为 MariaDB 在 10.4.3 之前将 JSON 实现为 LONGTEXT 别名uuid类型在不受支持时回落为varchar(36)normalizeType()中column.type uuid !this.uuidColumnTypeSuported时返回varchar且getColumnLength()对 UUID 生成策略固定补36长度MysqlDriver.ts#L887-L891。六、支持的列类型与默认长度完整支持列表与 MysqlDriver.supportedDataTypes 一致bit、int、integer、tinyint、smallint、mediumint、bigint、float、double、double precision、dec、decimal、numeric、fixed、bool、boolean、date、datetime、timestamp、time、year、char、nchar、national char、varchar、nvarchar、national varchar、text、tinytext、mediumtext、blob、longtext、tinyblob、mediumblob、longblob、enum、set、json、binary、varbinary、geometry、point、linestring、polygon、multipoint、multilinestring、multipolygon、geometrycollection、uuid、inet4、inet6注意uuid、inet4、inet6仅 MariaDB 可用且以对应版本实际引入为准如uuid需 MariaDB 10.7.0见上一节。未显式指定length/precision/scale时驱动使用dataTypeDefaultsMysqlDriver.ts#L294-L311补默认值varchar/nvarchar/national varchar默认长度255char/binary默认1decimal系默认precision 10, scale 0vector默认长度2048MySQL 未提供长度时的缺省值。几个值得注意的实现细节别名归一化normalizeType()会把 TypeScript 类型映射到具体列类型——Number→int、String→varchar、Date→datetime、Boolean→tinyint、Uint8Array子类 →blob同时把numeric/dec/fixed归一为decimal、nvarchar/national varchar归一为varcharMysqlDriver.ts#L750-L814。因此 schema 对比时不会因同义类型别名而误判列被修改别名长度上限maxAliasLength 63即 MySQL 标识符 63 字节限制影响查询构建时生成的别名布尔值与set的持久化格式preparePersistentValue()中Boolean写入时转为1/0set类型用DateUtils.simpleArrayToString()写成逗号分隔字符串读回时prepareHydratedValue()再用stringToSimpleArray()还原为数组MysqlDriver.ts#L621-L739。七、enum与set列类型enum列类型MySQL 的enum列用法与实体文档中的通用说明一致参见 enum 列类型。驱动侧对应行为枚举值在写入时统一转字符串 value读取时若数据库返回的数字恰好是enum数组中的合法成员则转回数字MysqlDriver.ts#L716-L724。set列类型set类型受mysql与mariadb支持官方文档给出了两种等价写法完整保留如下使用 TypeScript enumexport enum UserRole { ADMIN admin, EDITOR editor, GHOST ghost, } Entity() export class User { PrimaryGeneratedColumn() id: number Column({ type: set, enum: UserRole, default: [UserRole.GHOST, UserRole.EDITOR], }) roles: UserRole[] }使用字符串数组export type UserRoleType admin | editor | ghost Entity() export class User { PrimaryGeneratedColumn() id: number Column({ type: set, enum: [admin, editor, ghost], default: [ghost, editor], }) roles: UserRoleType[] }注意default必须是数组。默认值经normalizeDefault()处理时被包成单引号字符串ghost,editorMysqlDriver.ts#L842-L844与 MySQL 中SET列的默认值语法一致。八、Vector 类型官方文档说明MySQL 自 9.0 起支持 VECTOR 类型MariaDB 自 11.7 起支持向量。TypeORM 侧的证据vector已列入 supportedDataTypes并被归入withLengthColumnTypes即允许通过length指定向量维度MysqlDriver.ts#L217-L224默认长度2048仓库中带有针对 MySQL 向量列的数据库结构测试test/functional/database-schema/vectors/mysql/vector.test.ts可在本地连库运行以验证vector(N)列的建表行为。九、参数占位符、标识符转义与 upsert参数转义MySQL 驱动使用位置占位符createParameter()恒返回?MysqlDriver.ts#L1134-L1136。escapeQueryWithParameters()会把 SQL 中的命名参数:param、支持:params数组展开、函数型参数逐一替换为?并收集参数值这正是 QueryBuilder 各类setParameter值最终能安全传参的底层机制。标识符转义escape()使用反引号并转义内部反引号escape(columnName: string): string { return columnName.replaceAll(, ) }upsertinsertOrUpdateMySQL 系驱动声明的 upsert 能力是on-duplicate-key-updatesupportedUpsertTypes [on-duplicate-key-update]。InsertQueryBuilder生成 SQL 时的分支逻辑InsertQueryBuilder.ts#L679-L723onUpdate.overwrite为空数组时改写为INSERT IGNORE即冲突时静默跳过onUpdate.overwrite为列名数组时追加ON DUPLICATE KEY UPDATE col VALUES(col), ...onUpdate.columns为列名数组时追加ON DUPLICATE KEY UPDATE col :col, ...参数化版本。另外由于 MySQLmariadb除低版本外对 insert/delete/update 的 RETURNING 支持有限驱动通过_isReturningSqlSupported精细控制是否追加 RETURNING 子句MysqlDriver默认三者均为false仅 MariaDB 按版本打开见第五节对照表。事务方面MysqlDriver声明transactionSupport nested即支持基于SAVEPOINT的嵌套事务树表treeSupport true与 upsert见上能力也都已开启。小结接入 MySQL 系数据库前先npm install mysql2TypeORM 通过PlatformTools.load(mysql2)加载它可用driver选项替换为自定义客户端连接选项覆盖主机/凭据/字符集/时区/超时/大数/日期/安全等维度extra可透传任意底层库参数supportBigNumbers与bigNumberStrings在 TypeORM 中的实际默认值均为true驱动在连接时探测数据库版本按 MySQL 8.0/MariaDB 10.2、10.5、10.7 等阈值动态启用 CTE、RETURNING、uuid 列类型等能力列类型覆盖 MySQL 全家族set/enum/vector各有版本与默认值约定vector 默认 2048 维、MariaDB 11.7/MySQL 9.0upsert 基于ON DUPLICATE KEY UPDATE参数使用?占位符标识符使用反引号转义嵌套事务受支持。以上结论均可在仓库中复核驱动实现集中在 src/driver/mysql/含MysqlDriver.ts、MysqlQueryRunner.ts、MysqlDataSourceOptions.ts、MysqlConnectionCredentialsOptions.tsAurora 适配见 src/driver/aurora-mysql/向量列测试见 test/functional/database-schema/vectors/mysql/vector.test.ts。【免费下载链接】typeormTypeScript JavaScript ORM for Node.js — supports PostgreSQL, MySQL, MariaDB, SQLite, SQL Server, Oracle, and more.项目地址: https://gitcode.com/GitHub_Trending/ty/typeorm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考