配置
实体发现
¥Entity Discovery
你可以通过 entities
提供实体实例数组,或者让 ORM 在选定文件夹中查找你的实体。
¥You can either provide array of entity instances via entities
, or let the ORM look up your entities in selected folders.
MikroORM.init({
entities: [Author, Book, Publisher, BookTag],
});
我们还可以通过提供我们想要发现的实体的路径列表来使用基于文件夹的发现(也支持 glob)。这样,我们还需要指定 entitiesTs
,我们将路径指向 TS 源文件而不是 JS 编译文件(更多信息请参见 元数据提供程序)。
¥We can also use folder based discovery by providing list of paths to the entities we want to discover (globs are supported as well). This way we also need to specify entitiesTs
, where we point the paths to the TS source files instead of the JS compiled files (see more at Metadata Providers).
通过
ts-node
运行应用时使用entitiesTs
选项,因为 ORM 需要发现 TS 文件。如果你使用基于文件夹/文件的发现,请始终指定此选项。¥The
entitiesTs
option is used when running the app viats-node
, as the ORM needs to discover the TS files. Always specify this option if you use folder/file based discovery.
MikroORM.init({
entities: ['./dist/modules/users/entities', './dist/modules/projects/entities'],
entitiesTs: ['./src/modules/users/entities', './src/modules/projects/entities'],
// optionally you can override the base directory (defaults to `process.cwd()`)
baseDir: process.cwd(),
});
使用动态值(如
__dirname
)覆盖baseDir
时要小心,因为你最终可能会得到来自ts-node
的有效路径,但来自node
的路径无效。理想情况下,你应该保留process.cwd()
的默认值,以便无论你如何运行应用,始终具有相同的基本路径。¥Be careful when overriding the
baseDir
with dynamic values like__dirname
, as you can end up with valid paths fromts-node
, but invalid paths fromnode
. Ideally you should keep the default ofprocess.cwd()
there to always have the same base path regardless of how you run the app.
默认情况下,使用 ReflectMetadataProvider
来利用 reflect-metadata
。你还可以通过安装 @mikro-orm/reflection
来使用 TsMorphMetadataProvider
。此提供程序将分析你的实体源文件(或 .d.ts
类型定义文件)。如果你打算使用纯 JavaScript 而不是 TypeScript,请使用 EntitySchema
。
¥By default, ReflectMetadataProvider
is used that leverages the reflect-metadata
. You can also use TsMorphMetadataProvider
by installing @mikro-orm/reflection
. This provider will analyse your entity source files (or .d.ts
type definition files). If you aim to use plain JavaScript instead of TypeScript, use EntitySchema
.
你还可以实现自己的元数据提供程序并使用它。为此,请扩展
MetadataProvider
类。¥You can also implement your own metadata provider and use it instead. To do so, extend the
MetadataProvider
class.
import { MikroORM } from '@mikro-orm/core';
import { TsMorphMetadataProvider } from '@mikro-orm/reflection';
MikroORM.init({
metadataProvider: TsMorphMetadataProvider,
});
你还可以使用一些其他选项来调整发现过程:
¥There are also some additional options how you can adjust the discovery process:
MikroORM.init({
discovery: {
warnWhenNoEntities: false, // by default, discovery throws when no entity is processed
requireEntitiesArray: true, // force usage of class references in `entities` instead of paths
alwaysAnalyseProperties: false, // do not analyse properties when not needed (with ts-morph)
},
});
如果你禁用
discovery.alwaysAnalyseProperties
选项,则需要明确提供nullable
和ref
参数(如适用)。¥If you disable
discovery.alwaysAnalyseProperties
option, you will need to explicitly providenullable
andref
parameters (where applicable).
在 元数据提供程序 部分中阅读更多相关内容。
¥Read more about this in Metadata Providers sections.
调整默认类型映射
¥Adjusting default type mapping
从 v5.2 开始,我们可以根据推断出的属性类型改变 ORM 选择默认映射类型表示的方式。一个例子是 foo: string
到 varchar(255)
的映射。如果我们想在 postgres 中将此默认值更改为 text
类型,我们可以使用 discover.getMappedType
回调:
¥Since v5.2 we can alter how the ORM picks the default mapped type representation based on the inferred type of a property. One example is a mapping of foo: string
to varchar(255)
. If we wanted to change this default to a text
type in postgres, we can use the discover.getMappedType
callback:
import { MikroORM, Platform, Type } from '@mikro-orm/core';
const orm = await MikroORM.init({
discovery: {
getMappedType(type: string, platform: Platform) {
// override the mapping for string properties only
if (type === 'string') {
return Type.getType(TextType);
}
return platform.getDefaultMappedType(type);
},
},
});
onMetadata
钩子
¥onMetadata
hook
有时你可能想在元数据级别更改 ORM 的某些行为。你可以使用 onMetadata
钩子来修改元数据。假设你想将实体与不同的驱动程序一起使用,并且想要使用某些驱动程序特定的功能。使用 onMetadata
钩子,你可以动态修改元数据以满足驱动程序要求。
¥Sometimes you might want to alter some behavior of the ORM on metadata level. You can use the onMetadata
hook to modify the metadata. Let's say you want to use your entities with different drivers, and you want to use some driver specific feature. Using the onMetadata
hook, you can modify the metadata dynamically to fit the drivers requirements.
钩子将在填充默认值的内部过程之前执行,因此你可以将其视为修改实体定义中的属性选项,它们将受到尊重,例如在推断列类型时。
¥The hook will be executed before the internal process of filling defaults, so you can think of it as modifying the property options in your entity definitions, they will be respected e.g. when inferring the column type.
钩子可以是异步的,但只有当你使用异步
MikroORM.init()
方法而不是MikroORM.initSync()
时才会等待它。¥The hook can be async, but it will be awaited only if you use the async
MikroORM.init()
method, not with theMikroORM.initSync()
.
import { EntityMetadata, MikroORM, Platform } from '@mikro-orm/sqlite';
const orm = await MikroORM.init({
// ...
discovery: {
onMetadata(meta: EntityMetadata, platform: Platform) {
// sqlite driver does not support schemas
delete meta.schema;
},
},
});
或者,你也可以使用 afterDiscovered
钩子,该钩子在发现过程结束后触发。你可以在那里访问所有元数据,并根据需要添加或删除它们。
¥Alternatively, you can also use the afterDiscovered
hook, which is fired after the discovery process ends. You can access all the metadata there, and add or remove them as you wish.
import { EntityMetadata, MikroORM, Platform } from '@mikro-orm/sqlite';
const orm = await MikroORM.init({
// ...
discovery: {
afterDiscovered(storage: MetadataStorage) {
// ignore FooBar entity in schema generator
storage.reset('FooBar');
},
},
});
扩展
¥Extensions
从 v5.6 开始,可以通过 extensions
配置选项注册 ORM 扩展(如 SchemaGenerator
、Migrator
或 EntityGenerator
)。这将是在 v6 中提供 orm.migrator
等快捷方式的唯一支持方式,因此我们不再需要动态地需要这些依赖或将它们指定为可选的对等依赖(这两件事都会导致各种打包工具出现问题,例如 Webpack,或 Remix 或 Next.js 中使用的工具)。
¥Since v5.6, the ORM extensions like SchemaGenerator
, Migrator
or EntityGenerator
can be registered via the extensions
config option. This will be the only supported way to have the shortcuts like orm.migrator
available in v6, so we no longer need to dynamically require those dependencies or specify them as optional peer dependencies (both of those things cause issues with various bundling tools like Webpack, or those used in Remix or Next.js).
import { defineConfig } from '@mikro-orm/postgresql';
import { Migrator } from '@mikro-orm/migrations';
import { EntityGenerator } from '@mikro-orm/entity-generator';
import { SeedManager } from '@mikro-orm/seeder';
export default defineConfig({
dbName: 'test',
extensions: [Migrator, EntityGenerator, SeedManager],
});
SchemaGenerator
(以及MongoSchemaGenerator
)会自动注册,因为它不需要安装任何第三方依赖。¥The
SchemaGenerator
(as well asMongoSchemaGenerator
) is registered automatically as it does not require any 3rd party dependencies to be installed.
从 v6.3 开始,如果未明确注册,则再次动态检查扩展,因此安装给定的包(例如 @mikro-orm/seeder
)应该就足够了,就像在 v5 中一样。
¥Since v6.3, the extensions are again checked dynamically if not explicitly registered, so it should be enough to have the given package (e.g. @mikro-orm/seeder
) installed as in v5.
驱动程序
¥Driver
要选择驱动程序,你可以使用 type
选项,也可以提供驱动程序类引用。
¥To select driver, you can either use type
option, or provide the driver class reference.
type | 驱动程序名称 | dependency | note |
---|---|---|---|
mongo | MongoDriver | mongodb | * |
mysql | MySqlDriver | mysql2 | 与 MariaDB 兼容 |
mariadb | MariaDbDriver | mariadb | 与 MySQL 兼容 |
postgresql | PostgreSqlDriver | pg | 与 CockroachDB 兼容 |
mssql | MsSqlDriver | tedious | * |
sqlite | SqliteDriver | sqlite3 | * |
better-sqlite | BetterSqliteDriver | better-sqlite3 | * |
libsql | LibSqlDriver | libsql | * |
驱动程序和连接实现不直接从
@mikro-orm/core
模块导出。你可以从驱动程序包(例如import { PostgreSqlDriver } from '@mikro-orm/postgresql'
)导入它们。¥Driver and connection implementations are not directly exported from
@mikro-orm/core
module. You can import them from the driver packages (e.g.import { PostgreSqlDriver } from '@mikro-orm/postgresql'
).
你可以通过
driverOptions
将其他选项传递给底层驱动程序(例如mysql2
)。对象将被深度合并,覆盖所有内部使用的选项。¥You can pass additional options to the underlying driver (e.g.
mysql2
) viadriverOptions
. The object will be deeply merged, overriding all internally used options.
import { MySqlDriver } from '@mikro-orm/mysql';
MikroORM.init({
driver: MySqlDriver,
driverOptions: { connection: { timezone: '+02:00' } },
});
从 v3.5.1 开始,你还可以直接在 ORM 配置中设置时区:
¥From v3.5.1 you can also set the timezone directly in the ORM configuration:
MikroORM.init({
timezone: '+02:00',
});
连接
¥Connection
每个平台(驱动程序)都提供默认连接字符串,你可以通过 clientUrl
整体覆盖它,也可以通过以下选项之一部分覆盖它:
¥Each platform (driver) provides default connection string, you can override it as a whole through clientUrl
, or partially through one of following options:
export interface DynamicPassword {
password: string;
expirationChecker?: () => boolean;
}
export interface ConnectionOptions {
dbName?: string;
name?: string; // for logging only (when replicas are used)
clientUrl?: string;
host?: string;
port?: number;
user?: string;
password?: string | (() => string | Promise<string> | DynamicPassword | Promise<DynamicPassword>);
charset?: string;
multipleStatements?: boolean; // for mysql driver
pool?: PoolConfig; // provided by `knex`
}
下表显示默认客户端连接字符串:
¥Following table shows default client connection strings:
type | 默认连接 URL |
---|---|
mongo | mongodb://127.0.0.1:27017 |
mysql | mysql://root@127.0.0.1:3306 |
mariadb | mysql://root@127.0.0.1:3306 |
postgresql | postgresql://postgres@127.0.0.1:5432 |
读取副本
¥Read Replicas
要设置读取副本,你可以使用 replicas
选项。你只能提供 ConnectionOptions
接口的那些部分,它们将用于覆盖 master
连接选项。
¥To set up read replicas, you can use replicas
option. You can provide only those parts of the ConnectionOptions
interface, they will be used to override the master
connection options.
MikroORM.init({
dbName: 'my_db_name',
user: 'write-user',
host: 'master.db.example.com',
port: 3306,
replicas: [
{ user: 'read-user-1', host: 'read-1.db.example.com', port: 3307 },
{ user: 'read-user-2', host: 'read-2.db.example.com', port: 3308 },
{ user: 'read-user-3', host: 'read-3.db.example.com', port: 3309 },
],
});
¥Read more about this in Installation and Read Connections sections.
使用短暂令牌
¥Using short-lived tokens
许多云提供商都包含使用短期身份验证令牌连接到数据库实例的替代方法。MikroORM 通过回调函数支持动态密码,无论是同步还是异步。回调函数必须解析为字符串。
¥Many cloud providers include alternative methods for connecting to database instances using short-lived authentication tokens. MikroORM supports dynamic passwords via a callback function, either synchronous or asynchronous. The callback function must resolve to a string.
MikroORM.init({
dbName: 'my_db_name',
password: async () => someCallToGetTheToken(),
});
密码回调值将被缓存,要使此缓存无效,我们可以指定 expirationChecker
回调:
¥The password callback value will be cached, to invalidate this cache we can specify expirationChecker
callback:
MikroORM.init({
dbName: 'my_db_name',
password: async () => {
const { token, tokenExpiration } = await someCallToGetTheToken();
return { password: token, expirationChecker: () => tokenExpiration <= Date.now() }
},
});
onQuery
钩子和可观察性
¥onQuery
hook and observability
有时你可能想要更改生成的查询。一个用例可能是添加上下文查询提示以允许可观察性。在向 ORM 添加更原生的方法之前,你可以使用 onQuery
钩子手动修改所有查询。在执行每个查询之前,将触发该钩子。
¥Sometimes you might want to alter the generated queries. One use case for that might be adding contextual query hints to allow observability. Before a more native approach is added to the ORM, you can use the onQuery
hook to modify all the queries by hand. The hook will be fired for every query before its execution.
import { AsyncLocalStorage } from 'node:async_hooks';
const ctx = new AsyncLocalStorage();
// provide the necessary data to the store in some middleware
app.use((req, res, next) => {
const store = { endpoint: req.url };
ctx.run(store, next);
});
MikroORM.init({
onQuery: (sql: string, params: unknown[]) => {
const store = ctx.getStore();
if (!store) {
return sql;
}
// your function that generates the necessary query hint
const hint = createQueryHint(store);
return sql + hint;
},
});
命名策略
¥Naming Strategy
将实体映射到数据库表和列时,它们的名称将由命名策略定义。你可以选择 3 种基本命名策略:
¥When mapping your entities to database tables and columns, their names will be defined by naming strategy. There are 3 basic naming strategies you can choose from:
-
UnderscoreNamingStrategy
- 所有 SQL 驱动程序的默认值¥
UnderscoreNamingStrategy
- default of all SQL drivers -
MongoNamingStrategy
-MongoDriver
的默认值¥
MongoNamingStrategy
- default ofMongoDriver
-
EntityCaseNamingStrategy
- 使用未更改的实体和属性名称¥
EntityCaseNamingStrategy
- uses unchanged entity and property names
你还可以定义自己的自定义
NamingStrategy
实现。¥You can also define your own custom
NamingStrategy
implementation.
MikroORM.init({
namingStrategy: EntityCaseNamingStrategy,
});
在 命名策略 部分中阅读有关此内容的更多信息。
¥Read more about this in Naming Strategy section.
1:1 所有者的自动连接
¥Auto-join of 1:1 owners
默认情况下,当你选择反向时,1:1 关系的拥有方将自动连接,以便我们可以引用它。你可以通过 autoJoinOneToOneOwner
配置切换禁用此行为。
¥By default, owning side of 1:1 relation will be auto-joined when you select the inverse side so we can have the reference to it. You can disable this behaviour via autoJoinOneToOneOwner
configuration toggle.
MikroORM.init({
autoJoinOneToOneOwner: false,
});
使用过滤器自动连接 M:1 和 1:1 关系
¥Auto-join of M:1 and 1:1 relations with filters
自 v6 起,过滤器也应用于关系,作为 JOIN ON
条件的一部分。如果 M:1 或 1:1 关系目标上存在过滤器,则会自动连接此类实体,并且当外键定义为 NOT NULL
时,将导致 INNER JOIN
而不是 LEFT JOIN
。这对于通过过滤器实现软删除尤其重要,因为外键可能指向软删除的实体。当发生这种情况时,自动 INNER JOIN
将导致根本不返回这样的记录。你可以通过 autoJoinRefsForFilters
ORM 选项禁用此行为。
¥Since v6, filters are applied to the relations too, as part of JOIN ON
condition. If a filter exists on a M:1 or 1:1 relation target, such an entity will be automatically joined, and when the foreign key is defined as NOT NULL
, it will result in an INNER JOIN
rather than LEFT JOIN
. This is especially important for implementing soft deletes via filters, as the foreign key might point to a soft-deleted entity. When this happens, the automatic INNER JOIN
will result in such a record not being returned at all. You can disable this behavior via autoJoinRefsForFilters
ORM option.
MikroORM.init({
autoJoinRefsForFilters: false,
});
强制 UTC 时区
¥Forcing UTC Timezone
使用 forceUtcTimezone
选项强制将 Date
保存在不带时区的日期时间列中的 UTC 中。它适用于 MySQL(datetime
类型)和 PostgreSQL(timestamp
类型)。SQLite 默认执行此操作。
¥Use forceUtcTimezone
option to force the Date
s to be saved in UTC in datetime columns without timezone. It works for MySQL (datetime
type) and PostgreSQL (timestamp
type). SQLite does this by default.
MikroORM.init({
forceUtcTimezone: true,
});
将 null
值映射到 undefined
¥Mapping null
values to undefined
默认情况下,可空数据库列中的 null
值被水化为 null
。使用 forceUndefined
我们可以告诉 ORM 将这些 null
值转换为 undefined
。
¥By default null
values from nullable database columns are hydrated as null
. Using forceUndefined
we can tell the ORM to convert those null
values to undefined
instead.
MikroORM.init({
forceUndefined: true,
});
忽略查找查询中的 undefined
值
¥Ignoring undefined
values in Find Queries
ORM 会将 em.find()
查询中明确定义的 undefined
值视为 null
。如果你想忽略它们,请使用 ignoreUndefinedInQuery
选项:
¥The ORM will treat explicitly defined undefined
values in your em.find()
queries as null
s. If you want to ignore them instead, use ignoreUndefinedInQuery
option:
MikroORM.init({
ignoreUndefinedInQuery: true,
});
// resolves to `em.find(User, {})`
await em.find(User, { email: undefined, { profiles: { foo: undefined } } });
新实体的序列化
¥Serialization of new entities
刷新新实体后,所有关系都标记为已填充,就像从数据库加载实体一样。这将使已加载实体和刚插入实体的 e.toJSON()
的序列化输出对齐。
¥After flushing a new entity, all relations are marked as populated, just like if the entity was loaded from the db. This aligns the serialized output of e.toJSON()
of a loaded entity and just-inserted one.
在 v4 中,此行为默认被禁用,因此即使在刷新新实体后,序列化形式也仅包含其关系的 FK。我们可以通过 populateAfterFlush: false
选择加入这种旧行为。
¥In v4 this behaviour was disabled by default, so even after the new entity was flushed, the serialized form contained only FKs for its relations. We can opt in to this old behaviour via populateAfterFlush: false
.
MikroORM.init({
populateAfterFlush: false,
});
Population where 条件
¥Population where condition
这仅适用于 SELECT_IN 策略,因为 JOINED 策略暗示了推断。
¥This applies only to SELECT_IN strategy, as JOINED strategy implies the inference.
在 v4 中,当我们在 em.find()
和类似方法中使用填充提示时,将分析我们实体的查询,并提取部分内容并将其用于填充。以下示例将查找所有拥有给定 ID 的书籍的作者,并再次使用此 PK 条件填充他们的书籍集合,从而仅使这些书籍存在于这些集合中。
¥In v4, when we used populate hints in em.find()
and similar methods, the query for our entity would be analysed and parts of it extracted and used for the population. Following example would find all authors that have books with given IDs, and populate their books collection, again using this PK condition, resulting in only such books being in those collections.
// this would end up with `Author.books` collections having only books of PK 1, 2, 3
const a = await em.find(Author, { books: [1, 2, 3] }, { populate: ['books'] });
按照此示例,如果我们想加载所有书籍,我们需要单独的 em.populate()
调用:
¥Following this example, if we wanted to load all books, we would need a separate em.populate()
call:
const a = await em.find(Author, { books: [1, 2, 3] });
await em.populate(a, ['books']);
此行为已更改,现在可以通过 populateWhere
选项全局和本地配置。我们可以全局指定 PopulateHint.ALL
和 PopulateHint.INFER
之一,前者是 v5 中的默认值,后者是 v4 中的默认行为。在本地(通过 FindOptions
),我们还可以指定将传递给 em.populate()
调用的自定义 where 条件。
¥This behaviour changed and is now configurable both globally and locally, via populateWhere
option. Globally we can specify one of PopulateHint.ALL
and PopulateHint.INFER
, the former being the default in v5, the latter being the default behaviour in v4. Locally (via FindOptions
) we can also specify custom where condition that will be passed to em.populate()
call.
MikroORM.init({
// defaults to PopulateHint.ALL in v5
populateWhere: PopulateHint.INFER, // revert to v4 behaviour
});
自定义 Hydrator
¥Custom Hydrator
Hydrator 负责将数据库中的值分配给实体。你可以实现自定义 Hydrator
(通过扩展抽象 Hydrator
类):
¥Hydrator is responsible for assigning values from the database to entities. You can implement your custom Hydrator
(by extending the abstract Hydrator
class):
MikroORM.init({
hydrator: MyCustomHydrator,
});
自定义存储库
¥Custom Repository
你还可以全局注册自定义基础存储库(针对所有未指定 repository
选项的实体):
¥You can also register custom base repository (for all entities where you do not specify repository
option) globally:
你仍然可以将实体特定存储库与全局基础存储库结合使用。
¥You can still use entity specific repositories in combination with global base repository.
MikroORM.init({
entityRepository: CustomBaseRepository,
});
在 存储库 部分中阅读有关此内容的更多信息。
¥Read more about this in Repositories section.
严格模式和属性验证
¥Strict Mode and property validation
自 v4 以来,你需要确保使用正确类型的
validate: true
才能访问特定于驱动程序的方法(如 )。它会影响性能,通常不需要,只要你不通过Object.assign()
修改实体即可。¥Since v4.0.3 the validation needs to be explicitly enabled via
validate: true
. It has performance implications and usually should not be needed, as long as you don't modify your entities viaObject.assign()
.
MikroORM
会在实际持久化发生之前验证你的属性。它会尝试自动为你修复错误的数据类型。如果自动转换失败,它将引发错误。你可以启用严格模式来禁用此功能,并让 ORM 抛出错误。持久化实体时会触发验证。
¥MikroORM
will validate your properties before actual persisting happens. It will try to fix wrong data types for you automatically. If automatic conversion fails, it will throw an error. You can enable strict mode to disable this feature and let ORM throw errors instead. Validation is triggered when persisting the entity.
MikroORM.init({
validate: true,
strict: true,
});
在 属性验证 部分中阅读有关此内容的更多信息。
¥Read more about this in Property Validation section.
必需属性验证
¥Required properties validation
自 v5 起,迁移无需扩展即可存储。这意味着 mongo 用户现在也需要在其可选属性上使用 nullable: true
)。
¥Since v5, new entities are validated on runtime (just before executing insert queries), based on the entity metadata. This means that mongo users now need to use nullable: true
on their optional properties too).
可以通过 ORM 配置中的 validateRequired: false
全局禁用此行为。
¥This behaviour can be disabled globally via validateRequired: false
in the ORM config.
MikroORM.init({
validateRequired: false,
});
调试和日志记录
¥Debugging & Logging
你可以使用 debug
选项启用日志记录。将其设置为 true
以记录所有内容,或提供 'query' | 'query-params' | 'discovery' | 'info'
命名空间数组。
¥You can enable logging with debug
option. Either set it to true
to log everything, or provide array of 'query' | 'query-params' | 'discovery' | 'info'
namespaces.
MikroORM.init({
logger: (message: string) => myLogger.info(message), // defaults to `console.log()`
debug: true, // or provide array like `['query', 'query-params']`
highlight: false, // defaults to true
highlightTheme: { ... }, // you can also provide custom highlight there
});
在 调试 部分中阅读有关此内容的更多信息。
¥Read more about this in Debugging section.
自定义失败处理程序
¥Custom Fail Handler
如果在 em.findOneOrFail()
调用期间未找到任何实体,则会抛出 NotFoundError
。你可以通过 findOneOrFailHandler
(或如果启用了 严格模式,则为 findExactlyOneOrFailHandler
)自定义创建 Error
实例的方式:
¥When no entity is found during em.findOneOrFail()
call, a NotFoundError
will be thrown. You can customize how the Error
instance is created via findOneOrFailHandler
(or findExactlyOneOrFailHandler
if strict mode is enabled):
MikroORM.init({
findOneOrFailHandler: (entityName: string, where: Dictionary | IPrimaryKey) => {
return new NotFoundException(`${entityName} not found!`);
},
});
在 实体管理器 文档中阅读有关此内容的更多信息。
¥Read more about this in Entity Manager docs.
模式生成器
¥Schema Generator
以下示例显示了所有可能的选项及其默认值:
¥Following example shows all possible options and their defaults:
MikroORM.init({
schemaGenerator: {
disableForeignKeys: true, // try to disable foreign_key_checks (or equivalent)
createForeignKeyConstraints: true, // do not generate FK constraints
},
});
迁移
¥Migrations
在 migrations
命名空间下,你可以调整集成迁移支持的工作方式。以下示例显示了所有可能的选项及其默认值:
¥Under the migrations
namespace, you can adjust how the integrated migrations support works. Following example shows all possible options and their defaults:
MikroORM.init({
migrations: {
tableName: 'mikro_orm_migrations', // migrations table name
path: process.cwd() + '/migrations', // path to folder with migration files
glob: '!(*.d).{js,ts}', // how to match migration files (all .js and .ts files, but not .d.ts)
transactional: true, // run each migration inside transaction
disableForeignKeys: true, // try to disable foreign_key_checks (or equivalent)
allOrNothing: true, // run all migrations in current batch in master transaction
emit: 'ts', // migration generation mode
},
});
在 迁移 部分中阅读有关此内容的更多信息。
¥Read more about this in Migrations section.
种子
¥Seeder
以下示例显示了所有可能的选项及其默认值:
¥Following example shows all possible options and their defaults:
MikroORM.init({
seeder: {
path: './seeders',
defaultSeeder: 'DatabaseSeeder',
},
});
在 播种文档 中阅读更多相关内容。
¥Read more about this in seeding docs.
缓存
¥Caching
默认情况下,元数据发现结果被缓存。你可以禁用缓存,也可以调整其工作方式。以下示例显示了所有可能的选项及其默认值:
¥By default, metadata discovery results are cached. You can either disable caching, or adjust how it works. Following example shows all possible options and their defaults:
MikroORM.init({
metadataCache: {
enabled: true,
pretty: false, // allows to pretty print the JSON cache
adapter: FileCacheAdapter, // you can provide your own implementation here, e.g. with redis
options: { cacheDir: process.cwd() + '/temp' }, // options will be passed to the constructor of `adapter` class
},
});
在 元数据缓存 部分中阅读有关此内容的更多信息。
¥Read more about this in Metadata Cache section.
导入数据库转储文件(MySQL 和 PostgreSQL)
¥Importing database dump files (MySQL and PostgreSQL)
使用 mikro-orm database:import db-file.sql
,你可以导入数据库转储文件。这在启动应用时很有用,或者可以在测试中用于重置数据库。数据库转储通常有分布在多行上的查询,因此你需要以下配置。
¥Using the mikro-orm database:import db-file.sql
you can import a database dump file. This can be useful when kickstarting an application or could be used in tests to reset the database. Database dumps often have queries spread over multiple lines, and therefore you need the following configuration.
MikroORM.init({
...
multipleStatements: true,
...
});
为了增加安全性,应在生产环境中禁用此功能。
¥This should be disabled in production environments for added security.
使用原生私有属性
¥Using native private properties
如果我们想在实体内部使用原生私有属性,MikroORM 通过 Object.create()
创建实体实例的默认方法是不可行的(有关此内容的更多信息,请参阅 issue)。要强制使用实体构造函数,我们可以使用 forceEntityConstructor
切换:
¥If we want to use native private properties inside entities, the default approach of how MikroORM creates entity instances via Object.create()
is not viable (more about this in the issue). To force usage of entity constructors, we can use forceEntityConstructor
toggle:
MikroORM.init({
forceEntityConstructor: true, // or specify just some entities via `[Author, 'Book', ...]`
});
自动持久化创建的实体
¥Persist created entities automatically
当你通过 em.create()
创建新的实体实例时,它将自动标记为将来的持久性(在将其返回给你之前将在其上调用 em.persist()
)。如果你想禁用此行为,你可以全局设置 persistOnCreate: false
或通过 em.create(Type, data, { persist: false })
在本地覆盖它。
¥When you create new entity instance via em.create()
, it will be automatically marked for future persistence (em.persist()
will be called on it before its returned to you). In case you want to disable this behavior, you can set persistOnCreate: false
globally or override this locally via em.create(Type, data, { persist: false })
.
此标志仅影响
em.create()
,通过构造函数手动创建的实体仍然需要显式em.persist()
调用,或者它们需要成为某些已管理实体的实体图的一部分。¥This flag affects only
em.create()
, entities created manually via constructor still need an explicitem.persist()
call, or they need to be part of the entity graph of some already managed entity.
MikroORM.init({
persistOnCreate: false, // defaults to true since v5.5
});
使用全局身份映射
¥Using global Identity Map
在 v5 中,不再可能使用全局身份映射。这是一个常见问题,导致奇怪的错误,因为在没有请求上下文的情况下使用全局 EM 几乎总是错误的,我们总是需要为每个请求设置一个专用的上下文,这样它们就不会干扰。
¥In v5, it is no longer possible to use the global identity map. This was a common issue that led to weird bugs, as using the global EM without request context is almost always wrong, we always need to have a dedicated context for each request, so they do not interfere.
我们仍然可以通过 allowGlobalContext
配置或连接的环境变量 MIKRO_ORM_ALLOW_GLOBAL_CONTEXT
禁用此检查 - 这在单元测试中尤其方便。
¥We still can disable this check via allowGlobalContext
configuration, or a connected environment variable MIKRO_ORM_ALLOW_GLOBAL_CONTEXT
- this can be handy especially in unit tests.
MikroORM.init({
allowGlobalContext: true,
});
弃用警告
¥Deprecation warnings
默认情况下,执行已弃用的操作将导致记录弃用警告。默认记录器将依次在控制台上显示它。
¥By default, doing something that is deprecated will result in a deprecation warning being logged. The default logger will in turn show it on the console.
你可以忽略所有或仅特定的弃用警告。详情请参阅 日志中关于弃用警告的部分。
¥You can ignore all or only specific deprecation warnings. See Logging's section on deprecation warnings for details.
弃用警告的完整列表:
¥The full list of deprecation warnings:
label | message |
---|---|
D0001 | 配置文件的路径是从命令行参数推断出来的。相反,你应该设置 MIKRO_ORM_CLI_CONFIG 环境变量来指定路径,或者如果你确实必须使用命令行参数,请根据它们手动导入配置,然后将其传递给 init。 |
使用环境变量
¥Using environment variables
自 v4.0.3 以来,需要通过 明确启用验证。默认情况下,从根目录加载 .env
文件 - 也可以通过 MIKRO_ORM_ENV
环境变量设置要使用的环境文件的完整路径。
¥Since v4.5 it is possible to set most of the ORM options via environment variables. By default .env
file from the root directory is loaded - it is also possible to set full path to the env file you want to use via MIKRO_ORM_ENV
environment variable.
只有带有
MIKRO_ORM_
前缀的环境变量才能以这种方式加载,其他所有变量都将被忽略。如果你想访问.env
文件中定义的所有环境变量,请在你的应用中(或可能在你的 ORM 配置文件中)自行调用dotenv.register()
。¥Only env vars with
MIKRO_ORM_
prefix are be loaded this way, all the others will be ignored. If you want to access all your env vars defined in the.env
file, calldotenv.register()
yourself in your app (or possibly in your ORM config file).
环境变量始终优先于 ORM 配置。
¥Environment variables always have precedence over the ORM config.
示例 .env
文件:
¥Example .env
file:
MIKRO_ORM_TYPE = sqlite
MIKRO_ORM_ENTITIES = ./dist/foo/*.entity.js, ./dist/bar/*.entity.js
MIKRO_ORM_ENTITIES_TS = ./src/foo/*.entity.ts, ./src/bar/*.entity.ts
MIKRO_ORM_DB_NAME = test.db
MIKRO_ORM_MIGRATIONS_PATH = ./dist/migrations
MIKRO_ORM_MIGRATIONS_PATH_TS = ./src/migrations
MIKRO_ORM_POPULATE_AFTER_FLUSH = true
MIKRO_ORM_FORCE_ENTITY_CONSTRUCTOR = true
MIKRO_ORM_FORCE_UNDEFINED = true
支持选项的完整列表:
¥Full list of supported options:
环境变量 | 配置键 |
---|---|
MIKRO_ORM_CONTEXT_NAME | contextName |
MIKRO_ORM_BASE_DIR | baseDir |
MIKRO_ORM_TYPE | type |
MIKRO_ORM_ENTITIES | entities |
MIKRO_ORM_ENTITIES_TS | entitiesTs |
MIKRO_ORM_CLIENT_URL | clientUrl |
MIKRO_ORM_HOST | host |
MIKRO_ORM_PORT | port |
MIKRO_ORM_USER | user |
MIKRO_ORM_PASSWORD | password |
MIKRO_ORM_DB_NAME | dbName |
MIKRO_ORM_SCHEMA | schema |
MIKRO_ORM_LOAD_STRATEGY | loadStrategy |
MIKRO_ORM_BATCH_SIZE | batchSize |
MIKRO_ORM_USE_BATCH_INSERTS | useBatchInserts |
MIKRO_ORM_USE_BATCH_UPDATES | useBatchUpdates |
MIKRO_ORM_STRICT | strict |
MIKRO_ORM_VALIDATE | validate |
MIKRO_ORM_AUTO_JOIN_ONE_TO_ONE_OWNER | autoJoinOneToOneOwner |
MIKRO_ORM_PROPAGATE_TO_ONE_OWNER | propagateToOneOwner |
MIKRO_ORM_POPULATE_AFTER_FLUSH | populateAfterFlush |
MIKRO_ORM_FORCE_ENTITY_CONSTRUCTOR | forceEntityConstructor |
MIKRO_ORM_FORCE_UNDEFINED | forceUndefined |
MIKRO_ORM_FORCE_UTC_TIMEZONE | forceUtcTimezone |
MIKRO_ORM_TIMEZONE | timezone |
MIKRO_ORM_ENSURE_INDEXES | ensureIndexes |
MIKRO_ORM_IMPLICIT_TRANSACTIONS | implicitTransactions |
MIKRO_ORM_DEBUG | debug |
MIKRO_ORM_COLORS | colors |
MIKRO_ORM_DISCOVERY_WARN_WHEN_NO_ENTITIES | discovery.warnWhenNoEntities |
MIKRO_ORM_DISCOVERY_REQUIRE_ENTITIES_ARRAY | discovery.requireEntitiesArray |
MIKRO_ORM_DISCOVERY_ALWAYS_ANALYSE_PROPERTIES | discovery.alwaysAnalyseProperties |
MIKRO_ORM_DISCOVERY_DISABLE_DYNAMIC_FILE_ACCESS | discovery.disableDynamicFileAccess |
MIKRO_ORM_MIGRATIONS_TABLE_NAME | migrations.tableName |
MIKRO_ORM_MIGRATIONS_PATH | migrations.path |
MIKRO_ORM_MIGRATIONS_PATH_TS | migrations.pathTs |
MIKRO_ORM_MIGRATIONS_GLOB | migrations.glob |
MIKRO_ORM_MIGRATIONS_TRANSACTIONAL | migrations.transactional |
MIKRO_ORM_MIGRATIONS_DISABLE_FOREIGN_KEYS | migrations.disableForeignKeys |
MIKRO_ORM_MIGRATIONS_ALL_OR_NOTHING | migrations.allOrNothing |
MIKRO_ORM_MIGRATIONS_DROP_TABLES | migrations.dropTables |
MIKRO_ORM_MIGRATIONS_SAFE | migrations.safe |
MIKRO_ORM_MIGRATIONS_EMIT | migrations.emit |
MIKRO_ORM_SCHEMA_GENERATOR_DISABLE_FOREIGN_KEYS | migrations.disableForeignKeys |
MIKRO_ORM_SCHEMA_GENERATOR_CREATE_FOREIGN_KEY_CONSTRAINTS | migrations.createForeignKeyConstraints |
MIKRO_ORM_SEEDER_PATH | seeder.path |
MIKRO_ORM_SEEDER_PATH_TS | seeder.pathTs |
MIKRO_ORM_SEEDER_GLOB | seeder.glob |
MIKRO_ORM_SEEDER_EMIT | seeder.emit |
MIKRO_ORM_SEEDER_DEFAULT_SEEDER | seeder.defaultSeeder |
请注意,设置 MIKRO_ORM_CONTEXT_NAME
而不设置上表中的另一个配置环境变量会产生略有不同的效果。与其他环境变量结合使用时,最终配置对象被视为具有此 contextName
。如果没有其他环境变量,则在配置文件中搜索的是 contextName
的值。最终的配置对象是根据此值选择的。
¥Note that setting MIKRO_ORM_CONTEXT_NAME
without also setting another configuration environment variable from the table above has a slightly different effect. When combined with other environment variables, the final configuration object is considered to have this contextName
. Without other environment variables, it is a value of contextName
to search within the config file. The final config object is picked based on this value.
例如,假设不存在 .env
文件(或存在,但未设置上表中的任何内容)并运行:
¥For example, assume no .env
file is present (or is present, but sets nothing from the table above) and you run:
$ MIKRO_ORM_CONTEXT_NAME=example1 \
node ./dist/index.js
这将在标准路径中查找配置文件,并期望配置文件能够提供将 contextName
设置为 "example1" 的配置。
¥This will look for a config file in the standard paths, and will expect the config file to be able to provide a config with contextName
set to "example1".
如果你还设置了其他环境变量,MikroORM 仍将搜索配置文件并尝试使用此 contextName
找到配置,但如果找不到,它将基于此 contextName
和其余环境变量创建配置。
¥If you also set other environment variables, MikroORM will still search for a config file and try to a find a config with this contextName
, but if it can't find one, it will create a config based on this contextName
and the rest of the environment variables.
你还可以使用环境变量来控制 CLI 设置(你可以在 package.json
中设置):
¥There are also env vars you can use to control the CLI settings (those you can set in your package.json
):
环境变量 | 配置键 |
---|---|
MIKRO_ORM_CLI_CONFIG | (仅限 CLI) |
MIKRO_ORM_CLI_TS_CONFIG_PATH | (仅限 CLI) |
MIKRO_ORM_CLI_ALWAYS_ALLOW_TS | (仅限 CLI) |
MIKRO_ORM_CLI_USE_TS_NODE | (仅限 CLI) |
MIKRO_ORM_CLI_VERBOSE | (仅限 CLI) |