nestjs中使用typeorm-model-generator将数据库生成数据模型
一、关于typeorm-model-generator
的介绍
typeorm-model-generator简单点就是将现有的数据库中的表使用命令的方式自动生成typeorm的数据模型(注意前提是数据库要有表)
目前支持的数据库有
- icrosoft SQL Server
- PostgreSQL
- MySQL
- MariaDB
- Oracle Database
- SQLite
二、使用方式
-
全局安装模块(也可以使用
npx
,但是这种方式生成数据模型的时候会有点慢)$ npm i typeorm-module-generator -g
-
新创建一个文件夹
-
生成
package.json
的文件 -
在
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
表示先删除文件夹entitiesnpx 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的类,根据自己需求加
-
直接运行命令就可以在
entities
文件夹下生成全部的数据模型(目前格式有点丑,需要自己手动调整下)$ npm run db
三、在nestjs
中使用
虽然nestjs/typeorm中连接mysql的ormconfig.json中有个字段synchronize: true表示自动会根据模型生成表,但是我个人觉得仅仅适合个人在开发中玩玩,在团队开发中可能有专门的db管理数据库的,不可能让你直接代码同步生产数据表的,所以我们可以借用上面的方式数据库同步生成模型
-
使用
nest new demo
创建一个项目 -
在
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" }
-
手动将生成的模型改为
xx.entity.ts
四、一个多表操作的示例
-
用户表的
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
-
用户扩展表的
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
-
在
nestjs
项目中创建一个user.module
及基本文件nest g mo user nest g controller user nest g service user
-
运行命令让数据表生产数据模型
-
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; }
-
-
根据不同的
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; }
-
在控制器中使用
... @Post() async create(@Body() data: Extract<CreateUserDto, CreateUserExtendDto>) { return this.userService.create(data); } ...
-
在服务层中使用
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 '创建成功'; }
-
涉及多表操作可以将上面的代码加个事务上去
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(); }
评论区