首页
/ TypeORM DataSourceOptions 全解:从零配置到源码级消费链路

TypeORM DataSourceOptions 全解:从零配置到源码级消费链路

2026-09-05 21:17:54作者:鲍丁臣Ursa

在 TypeORM 中,一切数据访问都始于一个 DataSource 实例,而驱动这个实例行为的正是创建时传入的 DataSourceOptions 配置对象。本文基于 TypeORM 官方文档 数据源配置项,逐项讲解所有通用配置选项的语义、取值与默认值,并结合 BaseDataSourceOptions 等源码印证每个选项的真实作用点,读完你可以独立完成 MySQL / PostgreSQL 等数据库的数据源配置,并理解这些选项在 initialize() 流程中是如何被消费的。

一、什么是 DataSourceOptions

DataSourceOptions 是你创建新的 DataSource 实例时传入的数据源配置。不同 RDBMS 有自己的专属配置项,因此 DataSourceOptions 在源码中是一个联合类型:src/data-source/DataSourceOptions.ts 将它定义为各驱动配置类型的联合,例如 AuroraMysqlDataSourceOptions | PostgresDataSourceOptions | MysqlDataSourceOptions | ...,覆盖全部 19 个驱动目录(aurora-mysqlpostgresmysqlmssqlmongodbsqljs 等)。

每个驱动的选项接口都继承自公共基座 BaseDataSourceOptions,其中声明了所有数据库共享的配置项(entitiesloggingsynchronizecache 等),各驱动再叠加自己的连接凭据与专有选项。

二、通用数据源选项详解

1. type:数据库引擎类型(必填)

type 指定你使用的数据库引擎,是必填项。源码 DatabaseType 给出的完整取值为:

"aurora-mysql" | "aurora-postgres" | "better-sqlite3" | "capacitor"
| "cockroachdb" | "cordova" | "expo" | "mariadb" | "mongodb"
| "mssql" | "mysql" | "nativescript" | "oracle" | "postgres"
| "react-native" | "sap" | "spanner" | "sqljs"

驱动工厂根据该字段选择对应的 Driver 实现(见 DriverFactory)。

2. 连接信息与 extra

各驱动的 host / port / username / password / database 等连接凭据由各自接口定义,例如 MysqlDataSourceOptions 在基础凭据之外还暴露了 charsettimezoneconnectTimeoutacquireTimeoutreplication(主从读写分离)等 MySQL 专属选项;PostgresDataSourceOptions 则提供 schemauseUTCuuidExtensionextensionsreplication 等 PostgreSQL 专属选项,更多细节可参考 PostgreSQL 驱动文档MySQL 驱动文档

extra 选项用于把额外设置透传给底层驱动客户端(如 pgmysql2tediousmongodb)。从 BaseDataSourceOptions 的注释可以看出其定位:当驱动原生支持的设置没有被 TypeORM 建模为带类型的选项时,extra 是“逃生舱”;如果存在带类型的对应选项,应优先使用带类型的选项。

3. entities / subscribers / migrations:元数据加载

  • entities — 要加载的实体列表,接受实体类、Entity Schema 类以及目录路径(目录支持 glob 通配符),例如: entities: [Post, Category, "entities/*.js", "modules/**/entities/*.js"]。 从 BaseDataSourceOptions 的源码类型 MixedList<Function | string | EntitySchema> 可以确认:实体类、目录路径与 EntitySchema 对象可混合传入。文档示例中的独立 entitySchemas 字段是旧版写法,当前实现统一经由 entities 传入。实体定义详见 EntitiesEntity Schemas
  • subscribers — 要加载的订阅者,同样接受类与 glob 目录,例如: subscribers: [PostSubscriber, AppSubscriber, "subscribers/*.js", "modules/**/subscribers/*.js"]。详见 Subscribers
  • migrations — 要加载的迁移文件(类或 glob 路径)。详见 Migrations

4. logging / logger / maxQueryExecutionTime:日志三件套

  • logging — 是否启用日志。源码中其类型为 LoggerOptions,即 boolean | "all" | LogLevel[]:设为 true 时启用查询与错误日志;也可以指定具体类型数组,例如 ["query", "error", "schema"]
  • logger — 指定日志输出实现,取值为 "advanced-console""simple-console""formatted-console""file",默认 "advanced-console"(从 BaseDataSourceOptions 的源码类型看,还额外支持 "debug" 值)。也可以传入任意实现了 Logger 接口的自定义类,Logging 详见 Logging
  • maxQueryExecutionTime — 查询执行时间超过该毫秒阈值时,logger 会记录一条慢查询日志。注意 MySQL 驱动有个联动行为:在 MysqlDataSourceOptions 中,若同时设置 enableQueryTimeout: true,该值还会被用作底层查询的真实超时。

5. poolSize:连接池大小

poolSize 配置连接池中最大的活跃连接数。从源码看,各驱动会将其映射到底层驱动的不同池参数:

驱动 映射位置 底层参数
PostgreSQL PostgresDriver max: options.poolSize
MySQL / MariaDB MysqlDriver connectionLimit: credentials.poolSize ?? options.poolSize
MongoDB MongoDriver maxPoolSize
Oracle OracleDriver poolMax
CockroachDB CockroachDriver max

需要注意:better-sqlite3react-nativecapacitorsqljsspannermssql 等单连接型驱动在自己的选项接口中把 poolSize 重新声明为 never(例如 BetterSqlite3DataSourceOptions),意味着这些驱动不支持该选项,配置后会在类型层面被拦截。

6. namingStrategy / entityPrefix / entitySkipConstructor

  • namingStrategy — 用于命名字符串表中表和列的命名策略,实现 NamingStrategyInterface 接口的实例,缺省使用 DefaultNamingStrategy
  • entityPrefix — 给该数据源中所有表(或集合)加上统一前缀。
  • entitySkipConstructor — 从数据库反序列化实体时是否跳过构造函数。注意:跳过构造函数后,私有属性和默认属性值不会按预期工作(见 BaseDataSourceOptions 的注释)。

7. synchronize / dropSchema:两个“危险开关”

这两个选项都会自动改动数据库结构,源码中二者都在 initialize() 里被消费:

  • synchronize — 每次应用启动时自动创建/同步数据库 schema。文档明确警告:不要在生产环境使用,否则可能丢失生产数据;它更适合调试和开发阶段。替代方案是 CLI 的 schema:sync 命令。对 MongoDB 而言,由于 MongoDB 无 schema,该选项不创建表,仅通过创建索引来“同步”。
  • dropSchema — 每次数据源初始化时先丢弃整个 schema。同样只应出现在开发/调试环境,否则将清空全部生产数据。

DataSource.initialize() 的调用链可以看到执行顺序:

// 连接驱动后,按顺序执行:
await this.buildMetadatas()          // 1. 构建实体元数据
await this.driver.afterConnect()
if (this.options.dropSchema)         // 2. 先丢弃 schema
    await this.dropDatabase()
if (this.options.migrationsRun)      // 3. 自动执行迁移
    await this.runMigrations({ transaction: this.options.migrationsTransactionMode })
if (this.options.synchronize)        // 4. 最后同步 schema
    await this.synchronize()

dropSchemamigrationsRunsynchronize 的先后顺序是固定的,且任何一步失败都会 destroy() 当前数据源并抛出异常。

8. 迁移相关:migrationsRun / migrationsTransactionMode / migrationsTableName

  • migrationsRun — 每次应用启动时自动执行迁移(替代方案是 CLI 的 migrations:run 命令)。
  • migrationsTransactionMode — 控制迁移运行时的事务模式,取值为 "all"(所有迁移在一个事务中)/ "none"(不在事务中)/ "each"(每条迁移各自一个事务),见 BaseDataSourceOptions
  • migrationsTableName — 存放已执行迁移信息的表名(默认为 migrations)。

9. metadataTableName

存放表元数据信息的表名,默认为 typeorm_metadata(见 BaseDataSourceOptions 的注释)。

10. cache:实体结果缓存

cache 可设为布尔值直接开启,或传入对象细粒度配置。从源码 BaseDataSourceOptions 看,完整字段包括:

字段 说明 默认值
type 缓存类型:"database"(存入数据库独立表)/ "redis" / "ioredis" / "ioredis/cluster" "database"
provider 自定义缓存提供者的工厂函数(返回实现 QueryResultCache 的对象) -
tableName "database" 类型下的缓存表名 "query-result-cache"
options Redis 等外部缓存的连接配置 -
alwaysEnabled 设为 true 时,find 方法与 QueryBuilder 查询永远走缓存 -
duration 缓存过期时间(毫秒),可按查询覆盖 1000(1 秒)
ignoreErrors 缓存出错时是否忽略错误并直接回落到数据库 -

缓存机制详见 Cachingcache 配置生效的时点同样在 initialize() 中:若配置了缓存,会先执行 queryResultCache.connect() 再构建元数据(见 DataSource)。

11. isolateWhereStatements:where 子句括号隔离

设为 true 时自动为每个 where 子句包裹括号,防止多个条件拼接时产生运算符优先级问题。例如:

// 配置前
.where("user.firstName = :search OR user.lastName = :search")
// 生成:WHERE user.firstName = ? OR user.lastName = ?

// 配置后
// 生成:WHERE (user.firstName = ? OR user.lastName = ?)

12. invalidWhereValuesBehavior:null / undefined 值处理

控制高层操作(find 操作、repository 方法、EntityManager 方法)中 where 条件遇到 null / undefined 时的行为,不直接影响 QueryBuilder 的 .where()。源码 InvalidFindOptionsWhereBehavior 定义的取值:

  • null 行为:
    • 'ignore' — 跳过为 null 的属性
    • 'sql-null' — 把 null 转换为 SQL NULL
    • 'throw' — 抛出错误(默认)
  • undefined 行为:
    • 'ignore' — 跳过为 undefined 的属性
    • 'throw' — 抛出错误(默认)

示例:invalidWhereValuesBehavior: { null: 'sql-null', undefined: 'ignore' }。相关处理规则详见 Null and Undefined Handling

13. 源码中存在、值得了解的其他通用选项

BaseDataSourceOptions 的完整接口结构看,还有若干未在上文列出的通用选项可供使用:

  • isolationLevel — 事务默认隔离级别;未显式指定级别的 transaction() / startTransaction() 都将使用它,且必须在驱动支持的级别范围内(initialize() 会先行校验,见 validate-isolation-level)。
  • relationLoadStrategy — 关系加载策略:"join"(默认,用嵌套 JOIN)或 "query"(分开查询),嵌套 join 数据量大时建议改用后者;也可在单次 FindOptions / QueryBuilder 中覆盖。
  • typename — 为每个水合后的模型实体附加一个属性(值为实体名),作用类似 discriminator 字段。

三、完整配置示例

文档给出的 MySQL 数据源配置示例如下:

{
    host: "localhost",
    port: 3306,
    username: "test",
    password: "test",
    database: "test",
    logging: true,
    synchronize: true,
    entities: [__dirname + "/entities/**/*{.js,.ts}"],
    subscribers: [__dirname + "/subscribers/**/*{.js,.ts}"],
    entitySchemas: [__dirname + "/schemas/**/*.json"],
    migrations: [__dirname + "/migrations/**/*{.js,.ts}"]
}

结合源码,再补充一个启用缓存、日志分级与 where 值行为控制的 PostgreSQL 示例,展示各选项如何组合:

import { DataSource } from "typeorm"

const dataSource = new DataSource({
    type: "postgres",
    host: "localhost",
    port: 5432,
    username: "test",
    password: "test",
    database: "test",
    schema: "public",

    // 元数据加载:实体类 + glob 目录混排
    entities: [Post, Category, "entities/**/*.ts"],
    subscribers: "subscribers/**/*.ts",
    migrations: "migrations/**/*.ts",
    migrationsTableName: "migrations_history",
    migrationsTransactionMode: "each",

    // 日志与性能
    logging: ["query", "error", "schema"],
    logger: "advanced-console",
    maxQueryExecutionTime: 1000,
    poolSize: 10,

    // 开发期开关(生产环境务必关闭)
    synchronize: false,
    dropSchema: false,

    // 结果缓存
    cache: {
        type: "database",
        tableName: "query-result-cache",
        duration: 60000,
    },

    // where 条件行为
    isolateWhereStatements: true,
    invalidWhereValuesBehavior: { null: "sql-null", undefined: "ignore" },
    extra: {
        application_name: "my-service", // 透传给 pg 驱动
    },
})

await dataSource.initialize()

四、小结:配置项与消费时点的对应关系

DataSourceOptions 的设计遵循一个清晰的分层:公共选项集中在 BaseDataSourceOptions(类型、元数据加载、日志、同步、缓存、where 行为),驱动专属选项分散在各驱动的 *DataSourceOptions 接口中,由 DataSourceOptions 联合起来提供类型约束。而 dropSchemamigrationsRunsynchronize 这类“改变数据库结构”的选项,其实际执行点统一收敛在 DataSource.initialize() 的一条有序链路中,这为理解 TypeORM 的启动行为提供了确定的依据。掌握这些配置项的语义与生效位置后,你可以针对开发环境(开 synchronize 快速迭代)与生产环境(关闭危险开关、显式 poolSize、合理 cache 策略)分别组装出既安全又可维护的数据源配置。

登录后查看全文
热门项目推荐
相关项目推荐