一、关于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.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(); }
五、另外一种方式实现事务
这次将事务直接加到控制层
-
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 '创建成功'; }