> 文章列表 > NestJs使用MySQL创建多个实体

NestJs使用MySQL创建多个实体

NestJs使用MySQL创建多个实体

如果小伙伴还不会使用nestjs连接数据库的话 可以看我的上一篇文章 NestJs使用连接mysql企业级开发规范

关系

关系是指两个或多个表之间的联系。关系基于每个表中的常规字段,通常包含主键和外键。关系有三种:

名称 说明
一对一 主表中的每一行在外部表中有且仅有一个对应行。使用@OneToOne()装饰器来定义这种类型的关系
一对多/多对一 主表中的每一行在外部表中有一个或多的对应行。使用@OneToMany()和@ManyToOne()装饰器来定义这种类型的关系
多对多 主表中的每一行在外部表中有多个对应行,外部表中的每个记录在主表中也有多个行。使用@ManyToMany()装饰器来定义这种类型的关系

user.entity.ts

import {Column,Entity,PrimaryGeneratedColumn,
} from 'typeorm';@Entity() // 最终实现实体类
export class User {@PrimaryGeneratedColumn()id: number;@Column()username: string;@Column()password: string;
}

可以使用navicat 查看创建的user表
NestJs使用MySQL创建多个实体

再来创建一个profile.entity.ts

import {Column,Entity,JoinColumn,OneToOne,PrimaryGeneratedColumn,
} from 'typeorm';@Entity()
export class Profile {@PrimaryGeneratedColumn()id: number;@Column()gender: number;@Column()photo: string;@Column()address: string;
}

再来创建一个roles.entity.ts

import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from 'typeorm';@Entity()
export class Roles {@PrimaryGeneratedColumn()id: number;@Column()name: string;
}

再来创建一个logs.entity.ts

import {Column,Entity,JoinColumn,ManyToOne,PrimaryGeneratedColumn,
} from 'typeorm';@Entity()
export class Logs {@PrimaryGeneratedColumn()id: number;@Column()path: string;@Column()methods: string;@Column()data: string;@Column()result: number;
}

创建完之后别忘记把这个四个实体 添加到app.module.ts

import { Module } from '@nestjs/common';
import { UserModule } from './user/user.module';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as dotenv from 'dotenv';
import * as Joi from 'joi';
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
import { ConfigEnum } from './enum/config.enum';import { User } from './user/user.entity';
import { Profile } from './user/profile.entity';
import { Logs } from './logs/logs.entity';
import { Roles } from './roles/roles.entity';const envFilePath = `.env.${process.env.NODE_ENV || `development`}`;@Module({imports: [ConfigModule.forRoot({isGlobal: true,envFilePath,load: [() => dotenv.config({ path: '.env' })],validationSchema: Joi.object({NODE_ENV: Joi.string().valid('development', 'production').default('development'),DB_PORT: Joi.number().default(3306),DB_HOST: Joi.string().ip(),DB_TYPE: Joi.string().valid('mysql', 'postgres'),DB_DATABASE: Joi.string().required(),DB_USERNAME: Joi.string().required(),DB_PASSWORD: Joi.string().required(),DB_SYNC: Joi.boolean().default(false),}),}),TypeOrmModule.forRootAsync({imports: [ConfigModule],inject: [ConfigService],useFactory: (configService: ConfigService) =>({type: configService.get(ConfigEnum.DB_TYPE),host: configService.get(ConfigEnum.DB_HOST),port: configService.get(ConfigEnum.DB_PORT),username: configService.get(ConfigEnum.DB_USERNAME),password: configService.get(ConfigEnum.DB_PASSWORD),database: configService.get(ConfigEnum.DB_DATABASE),entities: [User, Profile, Logs, Roles],// 同步本地的schema与数据库 -> 初始化的时候去使用synchronize: configService.get(ConfigEnum.DB_SYNC),logging: process.env.NODE_ENV === 'development',// logging: ['error'],} as TypeOrmModuleOptions),}),// TypeOrmModule.forRoot({//   type: 'mysql',//   host: 'localhost',//   port: 3306,//   username: 'root',//   password: 'example',//   database: 'testdb',//   entities: [],//   // 同步本地的schema与数据库 -> 初始化的时候去使用//   synchronize: true,//   logging: ['error'],// }),UserModule,],controllers: [],providers: [],
})
export class AppModule {}

这样我们就创建好了表
NestJs使用MySQL创建多个实体
接下来我们来创建表和表之间的关系

NestJs使用MySQL创建多个实体
通过这个er图我们很容易看出表与表之间的关系。
接下来我们现在profile.entity.ts中创创建和user表的关系

一对一

一对一是一种 A 只包含一个 B 实例,而 B 只包含一个 A 实例的关系。 我们以User和Profile实体为例。

用户只能拥有一个配置文件,并且一个配置文件仅由一个用户拥有。

import {Column,Entity,JoinColumn,OneToOne,PrimaryGeneratedColumn,
} from 'typeorm';
import { User } from './user.entity';@Entity()
export class Profile {@PrimaryGeneratedColumn()id: number;@Column()gender: number;@Column()photo: string;@Column()address: string;@OneToOne(() => User)@JoinColumn()  // 会默认使用小驼峰 创建一个字段进行连接//  @JoinColumn({name:'userId'}) user: User;
}

这里我们将@OneToOne添加到user并将目标关系类型指定为User。 我们还添加了@JoinColumn,这是必选项并且只能在关系的一侧设置。 你设置@JoinColumn的哪一方,哪一方的表将包含一个"relation id"和目标实体表的外键。
同样,@JoinColumn必须仅设置在关系的一侧且必须在数据库表中具有外键的一侧。

 @OneToOne(() => User)// 使用函数 我们在需要的地方再次调用// 我们并不需要关系User类里面的内容

NestJs使用MySQL创建多个实体

多对一/一对多的关系

多对一/一对多是指 A 包含多个 B 实例的关系,但 B 只包含一个 A 实例。 让我们以User 和 Logs实体为例。 User 可以拥有多张 Logs,但每张 Log 仅由一位 user 拥有。

import {Column,Entity,PrimaryGeneratedColumn,OneToMany,ManyToMany,JoinTable,OneToOne,
} from 'typeorm';
import { Logs } from '../logs/logs.entity';@Entity()
export class User {@PrimaryGeneratedColumn()id: number;@Column()username: string;@Column()password: string;// typescript -> 数据库 关联关系 Mapping@OneToMany(() => Logs, (logs) => logs.user)logs: Logs[];
}

logs.entity.ts

import {Column,Entity,JoinColumn,ManyToOne,PrimaryGeneratedColumn,
} from 'typeorm';
import { User } from '../user/user.entity';@Entity()
export class Logs {@PrimaryGeneratedColumn()id: number;@Column()path: string;@Column()methods: string;@Column()data: string;@Column()result: number;// typescript 数据库 关联关系@ManyToOne(() => User, (user) => user.logs)//   user.logs 建立 OneToMany 的关系@JoinColumn()user: User;
}

这里我们将@OneToMany添加到logs属性中,并将目标关系类型指定为Logs。 你可以在@ManyToOne / @OneToMany关系中省略@JoinColumn,除非你需要自定义关联列在数据库中的名称。 @ManyToOne可以单独使用,但@OneToMany必须搭配@ManyToOne使用。 如果你想使用@OneToMany,则需要@ManyToOne。 在你设置@ManyToOne的地方,相关实体将有"关联 id"和外键。

NestJs使用MySQL创建多个实体

多对多的关系

多对多是一种 A 包含多个 B 实例,而 B 包含多个 A 实例的关系。 我们以User和 Roels实体为例。

user.entity.ts

import {Column,Entity,PrimaryGeneratedColumn,OneToMany,ManyToMany,JoinTable,OneToOne,
} from 'typeorm';
import { Logs } from '../logs/logs.entity';
import { Roles } from '../roles/roles.entity';
import { Profile } from './profile.entity';@Entity()
export class User {@PrimaryGeneratedColumn()id: number;@Column()username: string;@Column()password: string;// typescript -> 数据库 关联关系 Mapping@OneToMany(() => Logs, (logs) => logs.user)logs: Logs[];@ManyToMany(() => Roles, (roles) => roles.users)// 建立中间表@JoinTable({ name: 'users_roles' })roles: Roles[];@OneToOne(() => Profile, (profile) => profile.user)profile: Profile;
}

roles.entity.ts

import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from 'typeorm';
import { User } from '../user/user.entity';@Entity()
export class Roles {@PrimaryGeneratedColumn()id: number;@Column()name: string;@ManyToMany(() => User, (user) => user.roles)users: User[];
}

NestJs使用MySQL创建多个实体
到此为止 我们介绍了 一对一,一对多,多对多的关系,当然也都是从0到1 创建表的过程。恭喜,你成功进步了一大截。那么企业中都是0到1的场景吗?当然不是,那要是在原有的库上增加数据我们该怎么办呢?
接下来我们要介绍 旧项目中已有数据库我们怎么使用TypeORM
那么我们需要了解一下一个库:typeorm-model-generator
NestJs使用MySQL创建多个实体
局部安装

pnpm i -D typeorm-model-generator

然后 使用 package.json 新增一个命令

"generate:models": "typeorm-model-generator -h 127.0.0.1 -p 3306 -d testdb -u root -x 123456 -e mysql -o ./src/entities"

开始执行
NestJs使用MySQL创建多个实体
项目中会生成一个 entities文件夹

NestJs使用MySQL创建多个实体
注意
如果是旧项目 还是放在 entities 里面,后面新项目还是单独放

启动项目,启动成功,之前库也都存在了。