目 录CONTENT

文章目录

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

Administrator
2021-09-07 / 0 评论 / 0 点赞 / 6341 阅读 / 7830 字 / 正在检测是否收录...

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

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

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

目前支持的数据库有

  1. icrosoft SQL Server
  2. PostgreSQL
  3. MySQL
  4. MariaDB
  5. Oracle Database
  6. SQLite

二、使用方式

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

    $ npm i typeorm-module-generator -g 
    
  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.json和tsconfig.json文件
    • --ce pascal表示将类名转换首字母是大写的驼峰命名
    • --cp camel表示将数据库中的字段比如create_at转换为createAt
    • -a表示会继承一个BaseEntity的类,根据自己需求加
  5. 直接运行命令就可以在entities文件夹下生成全部的数据模型(目前格式有点丑,需要自己手动调整下)

    $ npm run db
    

三、在nestjs中使用

虽然nestjs/typeorm中连接mysql的ormconfig.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();
    }
    
0

评论区