Sequelize
本文档介绍如何在 Midway 中使用 Sequelize。
当前模块从 v3.4.0 开始已经重构,历史写法兼容,如果查询历史文档,请参考 这里。
相关信息:
描述 | |
---|---|
可用于标准项目 | ✅ |
可用于 Serverless | ✅ |
可用于一体化 | ✅ |
包含独立主框架 | ❌ |
包含独立日志 | ❌ |
和老写法的区别
如果想使用新版本的用法,请参考下面的流程,将老代码进行修改,新老代码不能混用。
升级方法:
- 1、请在业务依赖中显式添加
sequelize
和sequelize-typescript
- 2 、不再使用
BaseTable
装饰器,而直接使用sequelize-typescript
包导出的Table
装饰器 - 3、在
src/config.default
的sequelize
部分配置调整,参考下面的数据源配置部分- 3.1 修改为数据源的形式
sequelize.dataSource
- 3.2 将实体模型在数据源的
entities
字段中声明
- 3.1 修改为数据源的形式
安装依赖
$ npm i @midwayjs/sequelize@3 sequelize sequelize-typescript --save
或者在 package.json
中增加如下依赖后,重新安装。
{
"dependencies": {
"@midwayjs/sequelize": "^3.0.0",
"sequelize": "^6.21.3",
"sequelize-typescript": "^2.1.0"
// ...
},
"devDependencies": {
// ...
}
}
安装数据库 Driver
常用数据库驱动如下,选择你对应连接的数据库类型安装:
# for MySQL or MariaDB,也可以使用 mysql2 替代
npm install mysql --save
npm install mysql2 --save
# for PostgreSQL or CockroachDB
npm install pg --save
# for SQLite
npm install sqlite3 --save
# for Microsoft SQL Server
npm install mssql --save
# for sql.js
npm install sql.js --save
# for Oracle
npm install oracledb --save
# for MongoDB(experimental)
npm install mongodb --save
下面的文档,我们将以 mysql2
作为示例。
Directory structure
一个基础的参考目录结构如下。
MyProject
├── src
│ ├── config
│ │ └── config.default.ts
│ ├── entity
│ │ └── person.entity.ts
│ ├── configuration.ts
│ └── service
├── .gitignore
├── package.json
├── README.md
└── tsconfig.json
启用组件
在 src/configuration.ts
文件中启用组件。
import { Configuration, ILifeCycle } from '@midwayjs/core';
import { join } from 'path';
import * as sequelize from '@midwayjs/sequelize';
@Configuration({
imports: [
// ...
sequelize,
],
importConfigs: [join(__dirname, './config')],
})
export class MainConfiguration implements ILifeCycle {
// ...
}
模型定义
1、创建 Model(Entity)
我们通过模型和数据库关联,在应用中的模型就是数据库表,在 Sequelize 中,模型是和实体绑定的,每一个实体(Entity) 文件,即是 Model,也是实体(Entity)。
在示例中,需要一个实体,我们这里拿 person
举例。新建 entity 目录,在其中添加实体文件 person.entity.ts
,一个简单的实体如下。
// src/entity/person.entity.ts
import { Table, Model, Column, HasMany } from 'sequelize-typescript';
@Table
export class Hobby extends Model {
@Column
name: string;
}
@Table
export class Person extends Model {
@Column
name: string;
@Column
birthday: Date;
@HasMany(() => Hobby)
hobbies: Hobby[];
}
要注意,这里的实体文件的每一个属性,其实是和数据库表一一对应的,基于现有的数据库表,我们往上添加内容。
@Table
装饰器可以在不传递任何参数的情况下使用,更多参数请查看 定义选项 。
@Table({
timestamps: true,
...
})
export class Person extends Model {}
2、主键
主键 (id) 将从基类 Model 继承。 一般来说主键是 Integer 类型并且是自增的。
主键设置有两种方法,设置 @Column({primaryKey: true})
或者 @PrimaryKey
。
比如:
import { Table, Model, PrimaryKey } from 'sequelize-typescript';
@Table
export class Person extends Model {
@PrimaryKey
name: string;
}
3、时间列
主要指代的是 @CreatedAt
, @UpdatedAt
, @DeletedAt
单个装饰器标注的列。
比如:
import { Table, Model, CreatedAt, UpdatedAt, DeletedAt } from 'sequelize-typescript';
@Table
export class Person extends Model {
@CreatedAt
creationDate: Date;
@UpdatedAt
updatedOn: Date;
@DeletedAt
deletionDate: Date;
}
装饰器 | 描述 |
---|---|
@CreatedAt | 会设置 timestamps=true 和 createdAt='creationDate' |
@UpdatedAt | 会设置 timestamps=true 和 updatedAt='updatedOn' |
@DeletedAt | 会设置 timestamps=true , paranoid=true 和 deletedAt='deletionDate' |
4、普通列
@Column 装饰器用于标注普通列,可以在不传递任何参数的情况下使用。 但是因此需要能够自动推断 js 类型(详见类型推断)。
import { Table, Model, Column } from 'sequelize-typescript';
@Table
export class Person extends Model {
@Column
name: string;
}
或者指定列类型。
import { Table, Column, DataType } from 'sequelize-typescript';
@Table
export class Person extends Model {
@Column(DataType.TEXT)
name: string;
}
更多类型描述,请参考 这里。
比如:
import { Table, Model, Column, DataType } from 'sequelize-typescript'
@Table
export class Person extends Model {
@Column({
type: DataType.FLOAT,
comment: 'Some value',
...
})
value: number;
}
装饰器 | 描述 |
---|---|
@Column | 使用推导的 dataType 作为类型 |
@Column(dataType: DataType) | 显式设置 dataType |
@Column(options: AttributeOptions) | 设置 attribute options |
数据源配置
新版本我们启用了 数据源机制,在 src/config.default.ts
中配置:
// src/config/config.default.ts
import { Person } from '../entity/person.entity';
export default {
// ...
sequelize: {
dataSource: {
// 第一个数据源,数据源的名字可以完全自定义
default: {
database: 'test4',
username: 'root',
password: '123456',
host: '127.0.0.1',
port: 3306,
encrypt: false,
dialect: 'mysql',
define: { charset: 'utf8' },
timezone: '+08:00',
// 本地的时候,可以通过 sync: true 直接 createTable
sync: false,
// 实体形式
entities: [Person],
// 支持如下的扫描形式,为了兼容我们可以同时进行.js和.ts匹配️
entities: [
'entity', // 指定目录
'**/entity/*.entity.{j,t}s', // 通配加后缀匹配
],
},
// 第二个数据源
default2: {
// ...
},
},
},
};
模型关联
可以通过 HasMany
、@HasOne
、@BelongsTo
、@BelongsToMany
和 @ForeignKey
装饰器在模型中直接描述关系。
你不需要在数据库中创建外键也可以使用这个功能。
一对多
import { Table, Model, Column, ForeignKey, BelongsTo, HasMany } from 'sequelize-typescript';
@Table
export class Player extends Model {
@Column
name: string;
@Column
num: number;
@ForeignKey(() => Team)
@Column
teamId: number;
@BelongsTo(() => Team)
team: Team;
}
@Table
export class Team extends Model {
@Column
name: string;
@HasMany(() => Player)
players: Player[];
}