这是《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/usersGET请求- 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,结果与之前的相同。
共同学习,写下你的评论
评论加载中...
作者其他优质文章
 
                 
             
			 
					 
					