MikroORM
本章节介绍用户如何在 midway 中使用 MikroORM。 MikroORM 是基于数据映射器、工作单元和身份映射模式的 Node.js 的 TypeScript ORM。
MikroORM 的官网文档在 这里。
相关信息:
| 描述 | |
|---|---|
| 可用于标准项目 | ✅ |
| 可用于 Serverless | ✅ |
| 可用于一体化 | ✅ |
| 包含独立主框架 | ❌ |
| 包含独立日志 | ❌ |
关于升级
- 从
v3.14.0版本的组件开始,支持 mikro v5/v6 版本,由于 mikro v5 到 v6 有较大的变化,如从 mikro 老版本升级请提前阅读 Upgrading from v5 to v6 - 组件示例已更新为 v6 版本
安装组件
安装 mikro 组件,提供接入 mikro-orm 的能力。
$ npm i @midwayjs/mikro@3 @mikro-orm/core --save
或者在 package.json 中增加如下依赖后,重新安装。
{
"dependencies": {
"@midwayjs/mikro": "^3.0.0",
"@mikro-orm/core": "^6.0.2",
// ...
},
"devDependencies": {
// ...
}
}
同时,还需要引入对应数据库的适配包。
比如:
{
"dependencies": {
// sqlite
"@mikro-orm/sqlite": "^6.0.2",
// mysql
"@mikro-orm/mysql": "^6.0.2",
},
"devDependencies": {
// ...
}
}
更多驱动程序请查看 官方文档。
引入组件
在 src/configuration.ts 引入 mikro 组件,示例如下。
// configuration.ts
import { Configuration } from '@midwayjs/core';
import * as mikro from '@midwayjs/mikro';
import { join } from 'path';
@Configuration({
imports: [
// ...
mikro // 加载 mikro 组件
],
importConfigs: [
join(__dirname, './config')
]
})
export class MainConfiguration {
}
基础使用
和其他 orm 框架类 似,都是分为几个步骤:
- 1、定义 Entity
- 2、配置数据源
- 3、获取 EntityModel 进行调用
下面的更多 Entity 代码请查看 示例。
目录结构
一个基础的参考目录结构如下。
MyProject
├── src
│ ├── config
│ │ └── config.default.ts
│ ├── entity
│ │ ├── book.entity.ts
│ │ ├── index.ts
│ │ └── base.ts
│ ├── configuration.ts
│ └── service
├── .gitignore
├── package.json
├── README.md
└── tsconfig.json
定义 Entity
定义基础的 Entity。
// src/entity/BaseEntity.ts
import { PrimaryKey, Property } from '@mikro-orm/core';
export abstract class BaseEntity {
@PrimaryKey()
id!: number;
@Property()
createdAt: Date = new Date();
@Property({ onUpdate: () => new Date() })
updatedAt: Date = new Date();
}
定义实际的 Entity,包含一对多,多对多等关系。
// src/entity/book.entity.ts
import { Cascade, Collection, Entity, ManyToMany, ManyToOne, Property } from '@mikro-orm/core';
import { Author, BookTag, Publisher } from './index';
import { BaseEntity } from './base';
@Entity()
export class Book extends BaseEntity {
@Property()
title: string;
@ManyToOne(() => Author)
author: Author;
@ManyToOne(() => Publisher, { cascade: [Cascade.PERSIST, Cascade.REMOVE], nullable: true })
publisher?: Publisher;
@ManyToMany(() => BookTag)
tags = new Collection<BookTag>(this);
@Property({ nullable: true })
metaObject?: object;
@Property({ nullable: true })
metaArray?: any[];
@Property({ nullable: true })
metaArrayOfStrings?: string[];
constructor(title: string, author: Author) {
super();
this.title = title;
this.author = author;
}
}
配置数据源
mikro v5 和 v6 略有不同。
- mikro v6
- mikro v5
// src/config/config.default
import { Author, BaseEntity, Book, BookTag, Publisher } from '../entity';
import { join } from 'path';
import { SqliteDriver } from '@mikro-orm/sqlite';
export default (appInfo) => {
return {
mikro: {
dataSource: {
default: {
dbName: join(__dirname, '../../test.sqlite'),
driver: SqliteDriver, // 这里使用了 sqlite 做示例
allowGlobalContext: true,
// 实体形式
entities: [Author, Book, BookTag, Publisher, BaseEntity],
// 支持如下的扫描形式,为了兼容我们可以同时进行.js和.ts匹配️
entities: [
'entity', // 指定目录
'**/entity/*.entity.{j,t}s', // 通配加后缀匹配
],
}
}
}
}
}
// src/config/config.default
import { Author, BaseEntity, Book, BookTag, Publisher } from '../entity';
import { join } from 'path';
export default (appInfo) => {
return {
mikro: {
dataSource: {
default: {
dbName: join(__dirname, '../../test.sqlite'),
type: 'sqlite', // 这里使用了 sqlite 做示例
allowGlobalContext: true,
// 实体形式
entities: [Author, Book, BookTag, Publisher, BaseEntity],
// 支持如下的扫描形式,为了兼容我们可以同时进行.js和.ts匹配️
entities: [
'entity', // 指定目录
'**/entity/*.entity.{j,t}s', // 通配加后缀匹配
],
}
}
}
}
}
提示
mikro 的 entities 字段配置已经经过框架处理,该字段配置请不要参考原始文档。
增删查改
在业务代码中,可以使用 InjectRepository 注入 Repository 对象执行简单的查询操作。其它的增删改操作可以通过配合EntityManger 的 persist 和 flush 接口来实现,使用 InjectEntityManager 可以直接注入 EntityManager 对象,也可以通过repository.getEntityManager()获取。