这是《nestjs搭建通用业务框架》系列的第7篇,主要介绍了nestjs
中的TypeORM的具体使用方案。两种情况:1. 有数据库设计的情况,使用typeorm-model-generator
产生实体类;2. 无数据库的情况,可以手动创建实体类后,使用typeorm的synchronize
属性,来同步创建表格;
TypeORM上手
在前置的篇章中《nestjs搭建通用业务框架(5):数据库+配置》,我们有介绍如何集成TypeORM到我们的nest项目中。平时的使用,无非两种情况:
我们清楚的知道数据库及表格设计,我们不想去建TypeORM的实体ts文件;
我们清楚的知道实体类的字段类型,我们不想去建数据库,全交给ORM;
我们先来看第一种情况:
如何产生typeORM的实体类
typeorm-model-generator
:
针对
mysql
1
npx typeorm-model-generator -h localhost -d your-mysql-db -u root -x your-mysql-password -e mssql -o .
针对
progres
:1
npx typeorm-model-generator -h localhost -d postgres -u postgres -x !Passw0rd -e postgres -o .
参数说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Usage: typeorm-model-generator -h <host> -d <database> -p [port] -u <user> -x [password] -e [engine] Options: --help Show help [boolean] --version Show version number [boolean] -h, --host IP address/Hostname for database server [default: "127.0.0.1"] -d, --database Database name(or path for sqlite) [required] -u, --user Username for database server -x, --pass Password for database server [default: ""] -p, --port Port number for database server -e, --engine Database engine [choices: "mssql", "postgres", "mysql", "mariadb", "oracle", "sqlite"] [default: "mssql"] -o, --output Where to place generated models [default: "./output"] -s, --schema Schema name to create model from. Only for mssql and postgres. You can pass multiple values separated by comma eg. -s scheme1,scheme2,scheme3 --ssl [boolean] [default: false] |
-e
对应的数据库的类型-p
数据库服务器的端口-d
数据库的名称-u
数据库的用户名-s
为mssql
与postgres
设计的一个参数,可以设置schema的名称
比如,我们的项目中是这样用的:
由于事先已经建好了users
这个表格,里面就只有id
, username
,password
三个字段。
1 | npx typeorm-model-generator -h localhost -d nest-common -u root -x 123456 -e mysql -o . |
产生三个文件:
1 2 3 4 5 | . ├── entities │ └── Users.ts ├── ormconfig.json └── tsconfig.json |
这里只需要这个文件Users.ts
,然后大家可以把这个文件放置到src/entities
或者其他的src的目录中,重启项目。
Users.ts
文件的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'; @Index('username_Idx', ['username'], { unique: true }) @Entity('users', { schema: 'nest-common' }) export class Users { @PrimaryGeneratedColumn({ type: 'int', name: 'id' }) id: number; @Column('varchar', { name: 'username', unique: true, length: 32 }) username: string; @Column('varchar', { name: 'password', length: 255 }) password: string; } |
后续,我们建议使用
nest g res [Module-Name]
的方式来进行创建基础的CURD + 文件结构。
下面再来看第二种情况:
关于配置entities
路径
推荐配置src/config/devlopment.ts
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import * as path from 'path'; export const resolve = (dir) => path.join(path.resolve(__dirname, '../../'), dir); // 这里大家可以打印一下路径 // __dirname: /Users/macos/Projects/nestjs/nestjs-common-template/dist/config // 惊讶的发现,目录是dist目录中的config路径 export const config = { db: { // https://typeorm.io/#/connection-options/common-connection-options synchronize: true, logging: true, host: process.env.DB_HOST || '127.0.0.1', port: process.env.DB_PORT || 3306, username: process.env.DB_USER || 'root', password: process.env.DB_PASSWORD || '123456', database: process.env.DB_NAME || 'nest-common', // 这里对应的路径是 /Users/macos/Projects/nestjs/nestjs-common-template/dist/**/*.entity{.ts,.js} // 即 dist 目录中,所有以 .entity.ts 或者 .entity.js 结尾的文件 entities: [resolve('dist') + '/**/*.entity{.ts,.js}'], extra: { connectionLimit: 30, }, }, }; |
这里几个有意思的属性:
synchronize
:true
代表会从entities
属性产生SQL,并创建表格;如果,你的数据库中没有,那么则会创建表的SQL,并自动创建
测试:
删除
users
表格重启npm调试进程
刷新数据库,
users
表又回来了
logging
:true
代表执行SQL会打印在控制台中
entities
:TypeORM读取的实体类的文件夹,及文件名。
快速创建CURD服务
官方nest g
方案
使用命令nest g res users
,默认回车:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | nest g res users ? What transport layer do you use? (Use arrow keys) ❯ REST API GraphQL (code first) GraphQL (schema first) Microservice (non-HTTP) WebSockets ? Would you like to generate CRUD entry points? (Y/n) CREATE src/users/users.controller.spec.ts (566 bytes) CREATE src/users/users.controller.ts (894 bytes) CREATE src/users/users.module.ts (247 bytes) CREATE src/users/users.service.spec.ts (453 bytes) CREATE src/users/users.service.ts (609 bytes) CREATE src/users/dto/create-user.dto.ts (30 bytes) CREATE src/users/dto/update-user.dto.ts (169 bytes) CREATE src/users/entities/user.entity.ts (21 bytes) UPDATE src/app.module.ts (1150 bytes) |
是不是很方便。
使用ORM步骤:
打开
users/entities/user.entity.ts
,把之前生成的实体类加入进来,或者自己进行编辑。修改
users/users.module.ts
,导入ORM:1 2 3 4 5 6 7 8 9 10 11 12 13 14
import { Module } from '@nestjs/common'; import { UsersService } from './users.service'; import { UsersController } from './users.controller'; import { Users } from './entities/user.entity'; // 这里导入 import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ // 这里导入 imports: [TypeOrmModule.forFeature([Users])], controllers: [UsersController], providers: [UsersService], }) export class UsersModule {}
修改
users/users.service.ts
文件,添加get请求,并通过ORM操作数据库:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// ... import { InjectRepository } from '@nestjs/typeorm'; @Injectable() export class UsersService { constructor( // 这里添加了Repository @InjectRepository(Users) private readonly usersRepository: Repository<Users>, ) {} // ... async findAll() { // 返回usres表中的所有数据 return await this.usersRepository.find(), } // ... }
添加
users
一条信息,并测试:localhost:3000/users
GET请求1 2 3 4 5 6 7
[ { "id": 1, "username": "123", "password": "123" } ]
直接返回一个
json
数组。
nestjsx
方案
什么是
nestjsx
?一个致力于开发nestjs的扩展的github组织。
为什么要用
nestjsx
?官方:NestJS可能是几年前Node.js社区发生的最好的事情之一,为广泛的后端开发方面提供了一个真正重要的架构解决方案。但是,尽管它允许有效地创建RESTful应用程序,但缺少了一个重要的CRUD脚手架功能,而这个功能在许多其他HTTP框架中是存在的。这就是
Nestjsx/crud
问世的原因。nestjsx
的各个包的作用是什么@nestjsx/crud
- 核心包,它提供了@Crud()
装饰器,用于端点生成、全局配置、验证、辅助装饰器(文档)。@nestjsx/crud-typeorm
- TypeORM包,它为关系型数据库提供了带有CRUD
数据库操作方法的基础TypeOrmCrudService
@nestjsx/crud-request
- 请求生成器/解析器包,它提供了用于前端的RequestQueryBuilder
类和用于内部处理和验证后端查询/路径参数的RequestQueryParser
上手使用:
1 2 3 4 5 | # 安装 npm i @nestjsx/crud class-transformer class-validator # 使用 TypeORM npm i @nestjsx/crud-typeorm @nestjs/typeorm typeorm @nestjs/swagger |
修改users.service.ts
:
1 2 3 4 5 6 7 8 9 10 11 | import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { TypeOrmCrudService } from '@nestjsx/crud-typeorm'; import { Users } from './entities/user.entity'; @Injectable() export class UsersService extends TypeOrmCrudService<Users> { constructor(@InjectRepository(Users) repo) { super(repo); } } |
修改users.controller.ts
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import { Controller } from '@nestjs/common'; import { UsersService } from './users.service'; import { Users } from './entities/user.entity'; import { Crud, CrudController } from '@nestjsx/crud'; @Crud({ model: { type: Users, }, }) @Controller('users') export class UsersController implements CrudController<Users> { constructor(public service: UsersService) {} } |
再次请求localhost:3000/users
,结果与之前的相同。
共同学习,写下你的评论
评论加载中...
作者其他优质文章