nest 集成mysql typeorm 并实现数据迁移

前提假设本地的mysql环境安装完成

1、 安装typeorm和mysql

$ npm install --save @nestjs/typeorm typeorm mysql2 nestjs-config

2、导入到AppModule中
采用的是cofing的模式导入配置信息
异步配置参考地址

在src目录下创建config文件
database.config.ts

export default {
  type: process.env.DB_TYPE,
  host: process.env.DB_HOST,
  port: Number(process.env.DB_PORT),
  database: process.env.DB_DATABASE,
  username: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  logging: true,
};

.env

PREFIX=api/v1
PORT=XXXX

DB_TYPE=mysql
DB_HOST=localhost
DB_USERNAME=root
DB_PASSWORD=123456
DB_DATABASE=backstage
DB_PORT=3306
DB_LOGGING=true

SECRET=secret
import { ConfigModule, ConfigService } from 'nestjs-config';

@Module({
  imports: [
    // 配置加载配置文件
    ConfigModule.load(path.resolve(__dirname, 'config', '**/!(*.d).{ts,js}'), {
      modifyConfigName: (name) => name.replace('.config', ''),
    }),
    // mysql的连接
    TypeOrmModule.forRootAsync({
      useFactory: async (config: ConfigService) => ({
        type: config.get('database.type'),
        host: config.get('database.host'),
        port: config.get('database.port'),
        username: config.get('database.username'),
        password: config.get('database.password'),
        database: config.get('database.database'),
        entities: [__dirname + '/**/*.entity{.ts,.js}'],
        subscribers: [__dirname + './../subscribers/*.subscriber{.ts,.js}'],
        logging: config.get('database.logging'),
        synchronize: false,
        timezone: '+08:00', // 东八区
      }),
      inject: [ConfigService],
    }),
    UserModule,
  ],
  controllers: [AppController],
  providers: [
    AppService,
  ],
})

ormconfig.js

{
  "type": process.env.DB_TYPE, // 选用的数据库
  "host": process.env.DB_HOST, // 数据库地址
  "port": Number(process.env.DB_PORT), // 数据库端口
  "username": process.env.DB_USERNAME, // 数据库用户名
  "password": process.env.DB_PASSWORD, // 数据库密码
  "database": process.env.DB_DATABASE, // 数据库
  "synchronize": true, // 是否同步true表示会自动将src/entity里面定义的数据模块同步到数据库生成数据表(已经存在的表的时候再运行会报错) 生产环境应改为false 通过命令行操作更新数据库
  "dropSchema": true, // 删除数据库中的表
  "logging": false, // 是否打印日志,执行sql语句时候输出原生sql,也可以配置成一个数组["query", "error", "schema"]指定sql的执行类型
  "charset": "utf8mb4", // 编码
  "timezone": "local", // 时区,默认本地,也可以写"+8"
  "entityPrefix": "", // 给此数据库连接上的所有表(或集合)加的前缀。
  "entities": [ // 定义TypeORM需要查找的数据模型的,可以定义多个
      "src/modules/**/*.entity.{ts,js}"
  ],
  "migrations": [ // 数据迁移文件生成的地方
      "src/migration/**/*.ts"
  ],
  "subscribers": [ // 订阅(用的少)
      "src/subscribers/**/*.ts"
  ],
  "cli": { // 数据迁移工具使用的
      "entitiesDir": "src/modules",
      "migrationsDir": "src/migration",
      "subscribersDir": "src/subscriber"
  }
}
实现mysql typeorm 数据迁移的重点 个人学习

entitiesmigrations的路径要对应上 否则找不到文件 mysql不会生成对应的migration

 "entities": [ 
      "src/modules/**/*.entity.{ts,js}"
  ],
  "migrations": [ 
      "src/migration/**/*.ts"
  ],
  "cli": {
      "entitiesDir": "src/modules",
      "migrationsDir": "src/migration"
  }

配置package.json

"scripts": {
    "generate": "ts-node ./node_modules/typeorm/cli.js migration:generate -n Test",
    "db": "ts-node ./node_modules/typeorm/cli.js migration:run"
}

通过npm run generate 会在设置的migrations路径下生成对应的文件1646202649266-Test.ts
函数up为将要改变的数据库的内容
函数down为恢复之前的数据库的内容

import {MigrationInterface, QueryRunner} from "typeorm";

export class Test1646202649266 implements MigrationInterface {
    name = 'Test1646202649266'

    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE \`user\` DROP COLUMN \`grade\``);
        await queryRunner.query(`ALTER TABLE \`user\` CHANGE \`gender\` \`gender\` int NOT NULL COMMENT '性别' DEFAULT 0`);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE \`user\` CHANGE \`gender\` \`gender\` int NOT NULL COMMENT '性别' DEFAULT '0'`);
        await queryRunner.query(`ALTER TABLE \`user\` ADD \`grade\` int NULL COMMENT '分数'`);
    }
}

通过npm run db执行生成的migration文件 数据库就会变更为新的对应entity字段格式
至此 数据迁移完成

mysql数据库在service中使用

方式一: 通过Entity将数据库注入到Service中 在方法中通过this.xxx 调用服务

import {
  BadRequestException,
  HttpStatus,
  Injectable,
  Logger,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserDto } from './user.dto';
import { UserEntity } from './user.entity';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(UserEntity)
    private readonly userRepository: Repository<UserEntity>,
  ) {}

  async createUser(userDto: UserDto) {
    const oldUser = await this.userRepository.find({
      name: userDto.name,
    });
    if (oldUser.length) {
      throw new BadRequestException('用户已存在~');
    }
    userDto['hobby'] = userDto.hobby.toString();
    const createUser = await this.userRepository.create(userDto);
    const user = await this.userRepository.save(createUser);

    Logger.log('创建成功', `${user.name} 用户创建成功`);
    return user;
  }
}

方式二:connection 参考connection 增删改查

  async getPowerRoles(powerRolesDto): Promise<{ids: number[], keys: string[]}> {
    const list =  await getConnection()
      .createQueryBuilder(PowerRolesEntity, 'powerRoles')
      .where("powerRoles.isDel = 0")
      .andWhere("(powerRoles.roleId = :roleId)", { roleId: powerRolesDto.roleId })
      .getMany();

    const powerKeys = []
    for (const item of list) {
      const { powerId } = item
      const res = await this.powerRepository.findOne(powerId)
      if (res.isDel === 0) {
        // 未删除的才放入列表
        powerKeys.push(res.key)
      }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一套目前来说最好的nestjs实战教程,提供QQ长期问答服务. 本人从 08 年到 18 年一直从事于 PHP 的开发。从 18 年开始转向 Typescript+React+Nestjs 的技术栈。目前来说 React 应该是一个非常好用的前端框架,生态非常完善,并且十分灵活简单。Nestjs 则是 Node.js 中唯一且无敌存在的后端 web 框架。因为我个人从事这套技术栈开发已经 4 年多,所以颇有心得,做了这套 React18 视频教程和 Nestjs 实战视频教程。现在视频教程也是刚刚开始做了一部分,还在持续更新。使用 TS 全栈开发可以基本涵盖各种平台的方方面面,比如开发桌面应用的 Electron, 开发小程序的 Taro, 开发 Spa 中后台的 React,开发 SSR 网站的 next.js,开发移动应用的 React Native, 开发 CLI 的 Yargs, 以及开发后端的 Nestjs。基本学会一套,全面够用,再加上 Monorepo 组织结构,一个仓库所有平台都可以搞定。 包含以下知识点 - 掌握Nestjs框架的依赖注入,模块,提供者,生命周期等概念- 掌握DTO数据验证,响应序列化,异常过滤器等常用功能- 学会编写一些常用的class-validator验证约束- 熟练掌握Typeorm以及NestjsTypeorm结合开发- 学会整合Swagger输出Open API文档- 掌握TS装饰器以及反射元数据的定义和使用- 编写一些数据库相关的数据验证约束(比如树形表的同级别某字段唯一验证等)- 学会通过继承并魔改Nestjs源码编写自定义的全局验证器- 可以编写自定义的配置系统以及核心功能包- 学会自定义的代码组织方式(比如教程中我把默认的Nestjs应用改成Util+PluginModule模式)- 掌握编写一些常用的Util仓库(比如数据库,Redis,Restful)- 利用Yargs结合魔改后的框架可以编写一些自定义CLI命令(比如数据迁移,数据填充等)- 掌握如何利用阿里云/腾讯云推送邮件和短信- 掌握使用消息列队(MQ)的方式异步推送邮件和短信- 掌握守卫原理以及编写一些用户验证的守卫- 编写一个完善的用户系统(JWT认证,短信/邮件登录,短信/邮件注册,找回密码,绑定手机和邮箱等)- 熟练地通过编写装饰器去实现一些常用的功能- 通过SSE,WebSockets实现用户的上线,下线以及消息实时推送,消息广播等- 学会使用云存储来上传文件- 学会大文件断点雪川- 实现RBAC的权限系统- 理解请求范围概念以及性能方便的考量- 自己构建配置系统,实现配置验证以及通过YAML或数据库来进行动态配置- 通过适用Vscode进行Debug以及编写Jest测试来提升开发效率与程序的可用性- 学会使用Node来编写自定义的CLI命令- 利用NestCURD进行快速开发- 学会Graphql替代Restful写API- 使用Mongodb替代关系型数据库- 掌握一些常用的打包工具,比如通过ncc打包成单文件,通过pack打包成二进制等- 学会一些常用的部署方式,比如通过nginx+pm2反向代理部署,devops自动化CI,CD等- 学会使用pnpm workspaces来使用monreopo组织代码
nestjs是一个基于Node.js的Web框架,它提供了一种现代化的、模块化的、可扩展的方式来构建服务端应用程序。typeorm是一个强大的ORM(对象关系映射)库,它可以将数据库中的关系数据映射为对象,并且提供了一些便利的方法来操作这些对象。 nestjs整合typeorm可以帮助我们更方便地操作数据库,以下是nestjs整合typeorm的步骤: 1. 安装typeormnest-typeorm依赖: ``` npm install --save typeorm @nestjs/typeorm ``` 2. 在app.module.ts中引入typeormnest-typeorm: ``` import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { User } from './user.entity'; // 引入实体类 @Module({ imports: [ TypeOrmModule.forRoot({ type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: '123456', database: 'test', entities: [User], // 实体类列表 synchronize: true, }), TypeOrmModule.forFeature([User]), // 导入要用到的实体类 ], controllers: [AppController], providers: [AppService], }) export class AppModule {} ``` 3. 创建实体类: ``` import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column() age: number; @Column() email: string; } ``` 4. 在服务中使用: ``` import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { User } from './user.entity'; @Injectable() export class UserService { constructor( @InjectRepository(User) private readonly userRepository: Repository<User>, ) {} async findAll(): Promise<User[]> { return await this.userRepository.find(); } async create(user: User): Promise<User> { return await this.userRepository.save(user); } async update(id: number, user: User): Promise<void> { await this.userRepository.update(id, user); } async delete(id: number): Promise<void> { await this.userRepository.delete(id); } } ``` 以上是nestjs整合typeorm的基本步骤,通过使用nestjs整合typeorm可以更方便地操作数据库,并且nestjs提供了很多其他功能,例如异常处理、日志等。如果您有任何问题或者需要更详细的介绍,请告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值