nestjs中使用typeorm-model-generator将数据库生成数据模型

一、关于typeorm-model-generator的介绍

typeorm-model-generator简单点就是将现有的数据库中的表使用命令的方式自动生成typeorm的数据模型(注意前提是数据库要有表)

目前支持的数据库有

  • Microsoft SQL Server
  • PostgreSQL
  • MySQL
  • MariaDB
  • Oracle Database
  • SQLite

二、使用方式

  • 1、全局安装模块(也可以使用npx,但是这种方式生成数据模型的时候会有点慢)

    npm i -g typeorm-model-generator
    
  • 2、新创建一个文件夹

  • 3、生成package.json的文件

  • 4、在package.json文件下的scripts配置命令

    ...
    "scripts": {
      "db": "rm -rf entities & npx typeorm-model-generator -h localhost -d testdabase -p 3306 -u root -x root -e mysql -o entities --noConfig true --ce pascal --cp camel"
    }
    ...
    
    • rm -rf entities表示先删除文件夹entities
    • npx typeorm-model-generator如果全局安装了就不需要加npx没有全局安装就加上去
    • -h localhost -d 数据库名字 -p 端口 -u 用户名 -x 密码 -e 数据库类型
    • -o entities表示输出到指定的文件夹
    • --noConfig true表示不生成ormconfig.jsontsconfig.json文件
    • --ce pascal表示将类名转换首字母是大写的驼峰命名
    • --cp camel表示将数据库中的字段比如create_at转换为createAt
    • -a表示会继承一个BaseEntity的类,根据自己需求加
  • 5、直接运行命令就可以在entities文件夹下生成全部的数据模型(目前格式有点丑,需要自己手动调整下)

    npm run db
    

三、在nestjs中使用

虽然nestjs/typeorm中连接mysqlormconfig.json中有个字段synchronize: true表示自动会根据模型生成表,但是我个人觉得仅仅适合个人在开发中玩玩,在团队开发中可能有专门的db管理数据库的,不可能让你直接代码同步生产数据表的,所以我们可以借用上面的方式数据库同步生成模型

  • 1、使用nest new demo创建一个项目

  • 2、在package.json中配置命令

    ...
    "scripts": {
      "db": "rm -rf entities & npx typeorm-model-generator -h localhost -d testdabase -p 3306 -u root -x root -e mysql -o entities --noConfig true --ce pascal --cp camel"
    }
    ...
    
  • 3、手动将生成的模型改为xx.entity.ts

四、一个多表操作的示例

  • 1、用户表的sql语句

    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
      `uuid` varchar(150) COLLATE utf8_bin NOT NULL COMMENT 'uuid主键',
      `name` varchar(100) COLLATE utf8_bin NOT NULL COMMENT '姓名',
      `password` varchar(255) COLLATE utf8_bin NOT NULL COMMENT '密码',
      `email` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '邮箱',
      `mobile` varchar(11) COLLATE utf8_bin DEFAULT NULL COMMENT '手机号码',
      `gender` tinyint(4) DEFAULT '0' COMMENT '性别',
      `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uuid` (`uuid`),
      UNIQUE KEY `name` (`name`)
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
    
  • 2、用户扩展表的sql

    CREATE TABLE `user_extend` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `QQ` varchar(255) DEFAULT NULL,
      `address` varchar(255) DEFAULT NULL,
      `user_id` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
    
  • 3、在nestjs项目中创建一个user.module及基本文件

    nest g mo user
    nest g controller user
    nest g service user
    
  • 4、运行命令让数据表生产数据模型

    • user.entity.ts

      import {
        BaseEntity,
        Column,
        Entity,
        PrimaryGeneratedColumn,
      } from 'typeorm';
      
      @Entity('user', { schema: 'koa' })
      export class UserEntity extends BaseEntity {
        @PrimaryGeneratedColumn({
          type: 'int',
          name: 'id',
        })
        id: number;
      
        @Column('varchar', {
          nullable: false,
          unique: true,
          length: 150,
          name: 'uuid',
          generated: 'uuid',
        })
        uuid: string;
      
        @Column('varchar', {
          nullable: false,
          unique: true,
          length: 100,
          name: 'name',
        })
        name: string;
      
        @Column('varchar', {
          nullable: false,
          name: 'password',
        })
        password: string;
      
        @Column('varchar', {
          nullable: true,
          length: 100,
          name: 'email',
        })
        email: string | null;
      
        @Column('varchar', {
          nullable: true,
          length: 11,
          name: 'mobile',
        })
        mobile: string | null;
      
        @Column('tinyint', {
          nullable: true,
          default: () => 0,
          name: 'gender',
        })
        gender: number | null;
      
        @Column('timestamp', {
          nullable: false,
          default: () => 'CURRENT_TIMESTAMP',
          name: 'create_at',
        })
        createAt: Date;
      
        @Column('timestamp', {
          nullable: false,
          default: () => 'CURRENT_TIMESTAMP',
          name: 'update_at',
        })
        updateAt: Date;
      }
      
    • user.extend.entity.ts

      import {
        BaseEntity,
        Column,
        Entity,
        PrimaryGeneratedColumn,
      } from 'typeorm';
      
      @Entity('user_extend', { schema: 'koa' })
      export class UserExtendEntity extends BaseEntity {
        @PrimaryGeneratedColumn({
          type: 'int',
          name: 'id',
        })
        id: number;
      
        @Column('varchar', {
          nullable: true,
          name: 'QQ',
        })
        qq: string | null;
      
        @Column('varchar', {
          nullable: true,
          name: 'address',
        })
        address: string | null;
      
        @Column('int', {
          nullable: true,
          name: 'user_id',
        })
        userId: number | null;
      }
      
  • 5、根据不同的entity文件创建不同的dto文件

    export class CreateUserDto {
      readonly name: string;
      readonly password: string;
      readonly email?: string;
      readonly mobile?: string;
      readonly gender?: number;
    }
    export class CreateUserExtendDto {
      readonly QQ?: string;
      readonly address?: string;
    }
    
  • 6、在控制器中使用

    ...
    @Post()
    async create(@Body() data: Extract<CreateUserDto, CreateUserExtendDto>) {
      return this.userService.create(data);
    }
    ...
    
  • 7、在服务层中使用

    async create(data: Extract<CreateUserDto, CreateUserExtendDto>) {
      const { name, password, email, mobile, gender, qq, address } = data;
      const user = await this.userRepository.save({
        name,
        password,
        email,
        mobile,
        gender,
      });
      await this.userExtendRepository.save({ userId: user.id, qq, address });
      return '创建成功';
    }
    
  • 8、涉及多表操作可以将上面的代码加个事务上去

    async create(data: Extract<CreateUserDto, CreateUserExtendDto>) {
      const { name, password, email, mobile, gender, qq, address } = data;
      const connection = getConnection();
      const queryRunner = connection.createQueryRunner();
      await queryRunner.connect();
      await queryRunner.startTransaction();
      try {
        const user = await queryRunner.manager.insert<UserEntity>(UserEntity, {
          name,
          password,
          email,
          mobile,
          gender,
        });
        Logger.log(JSON.stringify(user), '插入user的数据');
        const userId = user.identifiers[0].id;
        await queryRunner.manager.insert<UserExtendEntity>(UserExtendEntity, {
          userId,
          qq,
          address,
        });
        await await queryRunner.commitTransaction();
        return '创建成功';
      } catch (e) {
        await queryRunner.rollbackTransaction();
        throw new BadRequestException('创建失败');
      }
    }
    
    async findAll() {
      return this.userRepository.find();
    }
    

五、另外一种方式实现事务

这次将事务直接加到控制层

  • 1、控制层的代码

    ...
    @Post()
    @Transaction()
    async create(
      @Body() data: Extract<CreateUserDto, CreateUserExtendDto>,
      @TransactionManager() manager: EntityManager,
    ) {
      return this.userService.create(data, manager);
    }
    ...
    
  • 2、在服务层中使用

    async create(
      data: Extract<CreateUserDto, CreateUserExtendDto>,
      manager: EntityManager,
    ) {
      const { name, password, email, mobile, gender, qq, address } = data;
      const user: { [propName: string]: any } = await manager.save(UserEntity, {
        name,
        password,
        email,
        mobile,
        gender,
      });
      Logger.log(JSON.stringify(user), '当前用户');
      // throw new Error('错误了')
      await manager.save(UserExtendEntity, {
        userId: user.id,
        qq,
        address,
      });
      return '创建成功';
    }
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水痕01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值