为了账号安全,请及时绑定邮箱和手机立即绑定

nestjs搭建通用业务框架(7):TypeORM进阶CURD操作

这是《nestjs搭建通用业务框架》系列的第7篇,主要介绍了nestjs中的TypeORM的具体使用方案。两种情况:1. 有数据库设计的情况,使用typeorm-model-generator产生实体类;2. 无数据库的情况,可以手动创建实体类后,使用typeorm的synchronize属性,来同步创建表格;

TypeORM上手

在前置的篇章中《nestjs搭建通用业务框架(5):数据库+配置》,我们有介绍如何集成TypeORM到我们的nest项目中。平时的使用,无非两种情况:

  1. 我们清楚的知道数据库及表格设计,我们不想去建TypeORM的实体ts文件;

  2. 我们清楚的知道实体类的字段类型,我们不想去建数据库,全交给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数据库的用户名

  • -smssqlpostgres设计的一个参数,可以设置schema的名称

比如,我们的项目中是这样用的:

由于事先已经建好了users这个表格,里面就只有idusernamepassword三个字段。

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,
    },
  },
};

这里几个有意思的属性:

  • synchronizetrue代表会从entities属性产生SQL,并创建表格;

    如果,你的数据库中没有,那么则会创建表的SQL,并自动创建

    测试:

  1. 删除users表格

  2. 重启npm调试进程

  3. 刷新数据库,users表又回来了

loggingtrue代表执行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步骤:

  1. 打开users/entities/user.entity.ts,把之前生成的实体类加入进来,或者自己进行编辑。

  2. 修改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 {}
  3. 修改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(),
      }
    
      // ...
    }
  4. 添加users一条信息,并测试:localhost:3000/users GET请求

    1
    2
    3
    4
    5
    6
    7
    [
        {
            "id": 1,
            "username": "123",
            "password": "123"
        }
    ]

    直接返回一个json数组。

nestjsx方案

  1. 什么是nestjsx

    一个致力于开发nestjs的扩展的github组织。

  2. 为什么要用nestjsx?

    官方:NestJS可能是几年前Node.js社区发生的最好的事情之一,为广泛的后端开发方面提供了一个真正重要的架构解决方案。但是,尽管它允许有效地创建RESTful应用程序,但缺少了一个重要的CRUD脚手架功能,而这个功能在许多其他HTTP框架中是存在的。这就是Nestjsx/crud问世的原因。

  3. 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,结果与之前的相同。


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
1413
获赞与收藏
683

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消