文章问题导向
typeorm的数据库实体如何编写?
数据库实体的监听装饰器如何使用?
如果你都有了答案,可以忽略本文章,或去nest学习导图寻找更多答案
注意
学习该文章,需要有一定的mysql知识基础
你已经会使用nest连接mysql,如果不会:去学习
实体设计
简单例子:下面讲解
import {
Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn} from "typeorm";
@Entity({
name: 'users' })
export class User {
@PrimaryGeneratedColumn()
id: number; 默认是int(11)类型
@Column()
username: string; 默认是varchar(255)类型
@Column()
password: string;
@Column()
status: boolean;
@CreateDateColumn()
created_at:date;
@UpdateDateColumn()
updated_at:date;
@DeleteDateColumn()
deleted_at:date;
}
装饰器说明
Entity 实体声明,程序运行时,自动创建的数据库表,@Entity({
name: 'users' }), name则是给该表命名,否则自动命名
PrimaryColumn 设置主键,没有自增
PrimaryGeneratedColumn 设置主键和自增,一般是id
Column 设置数据库列字段,在下面说明
CreateDateColumn 创建时间,自动填写
UpdateDateColumn 更新时间,自动填写
DeleteDateColumn 删除时间,自动填写
列字段参数
写法:
@Column("int")
@Column("varchar", {
length: 200 })
@Column({
type: "int", length: 200 }) 一般采用这种
常用选项参数:
@Column({
type: 'varchar', 列的数据类型,参考mysql
name: 'password', 数据库表中的列名,string,如果和装饰的字段是一样的可以不指定
length: 30, 列类型的长度,number
nullable: false, 是否允许为空,boolean,默认值是false
select:false, 查询数据库时是否显示该字段,boolean,默认值是true,密码一般使用false
comment: '密码' 数据库注释,stirng
})
password:string;
@Column({
type:'varchar',
unique: true, 将列标记为唯一列,唯一约束,比如账号不能有相同的
})
username:string;
@Column({
type:'tinyint',
default: () => 1, 默认值,创建时自动填写的值
comment: '0:禁用,1:可用'
})
status:number;
@Column({
type: 'enum',
enum: ['male', 'female'], 枚举类型,只能是数组中的值
default: 'male' 默认值
})
gender:string;
完整例子
import {
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity({
name: 'users' })
export class UsersEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({
type: 'varchar',
length: 30,
nullable: false,
unique: true,
})
username: string;
@Column({
type: 'varchar',
name: 'password',
length: 100,
nullable: false,
select: false,
comment: '密码',
})
password: string;
@Column({
type: 'varchar',
length: 11,
select: false,
nullable: true,
comment: '手机号码',
})
mobile: string;
@Column({
type: 'varchar',
length: 50,
select: false,
nullable: true,
comment: '邮箱',
})
email: string;
@Column({
type: 'enum',
enum: ['male', 'female'],
default: 'male',
})
gender: string;
@Column({
type: 'tinyint',
default: () => 1,
comment: '0:禁用,1:可用',
})
status: number;
@CreateDateColumn({
type: 'timestamp',
nullable: false,
name: 'created_at',
comment: '创建时间',
})
createdAt: Date;
@UpdateDateColumn({
type: 'timestamp',
nullable: false,
name: 'updated_at',
comment: '更新时间',
})
updatedAt: Date;
@DeleteDateColumn({
type: 'timestamp',
nullable: true,
name: 'deleted_at',
comment: '删除时间',
})
deletedAt: Date;
}
+------------+-----------------------+------+-----+----------------------+--------------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-----------------------+------+-----+----------------------+--------------------------------------------------+
| id | int | NO | PRI | NULL | auto_increment |
| status | tinyint | NO | | 1 | |
| username | varchar(30) | NO | UNI | NULL | |
| gender | enum('male','female') | NO | | male | |
| created_at | timestamp(6) | NO | | CURRENT_TIMESTAMP(6) | DEFAULT_GENERATED |
| updated_at | timestamp(6) | NO | | CURRENT_TIMESTAMP(6) | DEFAULT_GENERATED on update CURRENT_TIMESTAMP(6) |
| mobile | varchar(11) | YES | | NULL | |
| email | varchar(50) | YES | | NULL | |
| password | varchar(100) | NO | | NULL | |
+------------+-----------------------+------+-----+----------------------+--------------------------------------------------+
抽离部分重复的字段:使用继承
baseEntity:将id,创建时间,更新时间,删除时间抽离成BaseEntity
import {
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
} from 'typeorm';
@Entity()
export class BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@CreateDateColumn({
type: 'timestamp',
nullable: false,
name: 'created_at',
comment: '创建时间',
})
createdAt: Date;
@UpdateDateColumn({
type: 'timestamp',
nullable: false,
name: 'updated_at',
comment: '更新时间',
})
updatedAt: Date;
@DeleteDateColumn({
type: 'timestamp',
nullable: false,
name: 'deleted_at',
comment: '删除时间',
})
deletedAt: Date;
}
users表继承自baseEntity,就不需要写创建时间,修改时间,自增ID等重复字段了
其他的表也可以继承自baseEntity,减少重复代码
import {
Column,Entity } from 'typeorm';
import {
BaseEntity } from './user.baseEntity';
@Entity({
name: 'users' })
export class UsersEntity extends BaseEntity {
继承
@Column({
type: 'varchar',
length: 30,
nullable: false,
unique: true,
})
username: string;
@Column({
type: 'varchar',
name: 'password',
length: 100,
nullable: false,
select: false,
comment: '密码',
})
password: string;
@Column({
type: 'varchar',
length: 11,
select: false,
nullable: true,
comment: '手机号码',
})
mobile: string;
@Column({
type: 'varchar',
length: 50,
select: false,
nullable: true,
comment: '邮箱',
})
email: string;
@Column({
type: 'enum',
enum: ['male', 'female'],
default: 'male',
})
gender: string;
@Column({
type: 'tinyint',
default: () => 1,
comment: '0:禁用,1:可用',
})
status: number;
}
实体监听装饰器
其实是typeorm在操作数据库时的生命周期,可以更方便的操作数据
查找后:@AfterLoad
插入前:@BeforeInsert
插入后:@AfterInsert
更新前:@BeforeUpdate
更新后:@AfterUpdate
删除前:@BeforeRemove
删除后:@AfterRemove
AfterLoad例子:其他的装饰器是一样的用法
import {
Column,
Entity,
AfterLoad,
} from 'typeorm';
@Entity({
name: 'users' })
export class UsersEntity extends BaseEntity {
查找后,如果age小于20,让age = 20
@AfterLoad() 装饰器固定写
load() {
函数名字随你定义
console.log('this', this);
if (this.age < 20) {
this.age = 20;
}
}
@Column()
username: string;
@Column()
password: string;
@Column({
type: 'tinyint',
default: () => 18,
})
age: number;
}
使用生命周期前是18,查找后就变成了20
{
"status": 200,
"message": "请求成功",
"data": {
"id": 1,
"username": "admin",
"age": 20,
}
}
学习更多
nest学习导图