createNestengineering

Of course, the first step is to create a Nest project, Nest and Typeorem are mainly based on TS, so first need to install TS module:

yarn global add typescript
Copy the code

Then install nest scaffolding:

yarn global add @nestjs/cli
Copy the code

Using scaffolding to create nest project:

nest new NestWithOrm
Copy the code

The nest-with-Orm project will be generated and renamed to NestWithOrm. Then go to the NestWithOrm folder and run the following command:

yarn run start
Copy the code

Open a browser, access port 3000, and see the HelloWord output. Ts and app.controller.ts files are deleted first. We need to organize the directory structure ourselves and write controllers, etc.

organizationNeststructure

The general MVC style is divided into service layer, Entity layer, Controller layer, etc. We also organize the project with a similar structure, and create several folders of Entity, Controller, Service and provider under SRC. The directory structure of SRC will be as follows:

SRC | - the entity # entity class code | | - controller # placed control layer - service # # | to place service layer code -- the module module code | -- app. The module. The ts # Provides injectable objects as well as controller registration '----main.ts # entry functionsCopy the code

integrationTypeOrm

Install dependencies

Nest module supports YARN Add --save @nestjs/ Typeorm # Typeorm core module YARN add Typeorm --save # Provide metadata for Typeorm decorators to add support yarn Add Mapadd install @types/node --save # Install the database driver yarn add mysql2 --saveCopy the code

Defining entity Classes

Create a new user.ts under SRC /entity and write an entity class like this:

// User.ts
import {Entity, Column, PrimaryGeneratedColumn} from 'typeorm'@ the Entity (" user ")export class User {
    @PrimaryGeneratedColumn() id: number // Primary key, increment
    @Column() name: string
    @Column() password: string
}
Copy the code

Define the service base class

Define a service base class that exposes the basic CURD methods, which can be directly inherited by the corresponding service classes of each entity, so that the basic methods do not need to be written again for each service class.

Create a BaseService. Ts file in the SRC /service directory with the following contents:

// BaseService.ts
import { Repository, DeleteResult, SaveOptions, FindConditions, RemoveOptions } from "typeorm";
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
import { Injectable } from "@nestjs/common";

/** * service base class, implement some common basic methods, so that you do not have to write each service class again, directly inherit the class */
@Injectable() export class BaseService<T> {
    protected readonly repository: Repository<T>;
    constructor(repository: Repository<T>) {
        this.repository = repository;
    }

    asyncsaveOne(entity: T, options? : SaveOptions):Promise<T> {
        return this.repository.save(entity, options);
    }

    asyncsaveMany(entities: T[], options? : SaveOptions):Promise<T[]> {
        return this.repository.save(entities, options);
    }

    asyncfindOne(options? : FindConditions<T>):Promise<T> {
        return this.repository.findOne(options);
    }

    asyncfindMany(options? : FindConditions<T>):Promise<T[]> {
        return this.repository.find(options);
    }

    async findAll(): Promise<T[]> {
        return this.repository.find();
    }

    asyncremoveOne(entity: T, options? : RemoveOptions):Promise<T> {
        return this.repository.remove(entity, options);
    }

    asyncremoveMany(entities: T[], options? : RemoveOptions):Promise<T[]> {
        return this.repository.remove(entities, options);
    }

    async delete(options? : FindConditions<T>):Promise<DeleteResult> {
        return this.repository.delete(options);
    }

    async update(conditions: number | FindConditions<T>, newValue: QueryDeepPartialEntity<T>): Promise<number> {
        let updateResult = 1;
        await this.repository.update(conditions, newValue).catch(e= > updateResult = 0);
        returnupdateResult; }}Copy the code

Define the service class corresponding to the entity

Create the userservice. ts file in the SRC /service directory as follows:

// UserService.ts
import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';

import { BaseService } from './BaseService';

@Injectable()
export class UserService extends BaseService<User> {
    constructor(
        @InjectRepository(User) private readonly userRep: Repository<User>
    ) {
        super(userRep); }}Copy the code

definecontroller

Create a new userController. ts file in the SRC /controller directory and define the contents of the control layer as follows:

import { Controller, Get, Param } from '@nestjs/common';
import { UserService } from '.. /service/UserService';

@Controller("user")
export class AppController {
    // Inject service via constructor
    constructor(
        private readonly userService: UserService
    ){}
    
    // Define a route
    @Get("/")
    async getUser(): Promise<User> {
        let user = await this.userRep.save({name: 'user1'.password: 'pass1'});
        return await this.userService.findOne({name: 'user1'}); }}Copy the code

Defining service modules

SRC /module: SRC /module: ServiceModule. Ts: SRC /module: ServiceModule. Ts: SRC /module: ServiceModule.

import {Module} from '@nestjs/common';
import {TypeOrmModule} from '@nestjs/typeorm';

import {User} from 'src/entity/User';
import {UserService} from 'src/service/UserService';

@Module({
    imports: [
        // Configure the data source
        TypeOrmModule.forRoot({
            type: 'mysql'.host: 'localhost'.port: 3306.username: 'root'.password: 'root'.database: 'test'.autoLoadEntities: true.synchronize: false
        }),
        // Import entities
        TypeOrmModule.forFeature([
            User,
        ]),
    ],
    // The service class acts as the provider
    providers: [
        UserService,
    ],
    // Export to be used by other modules
    exports: [
        UserService,
    ]
})

export class ServiceModule {}
Copy the code

Register the service module with the root module

Finally, register the service module and controller with the root module as follows:

import { Module } from '@nestjs/common'
import { UserController } from './controller/UserController'
import { ServiceModule } from './module/ServiceModule';

@Module({
  imports: [ServiceModule], // Introduce the DAO layer module
  controllers: [UserController], // Register all controllers
})
export class AppModule {}
Copy the code

The introduction ofreflect-metadata

Finally, TypeOrm decorators need support from the Reflect-metadata module, which we need to explicitly introduce in the entry function main.ts. To be placed on the first line of the introduction, the SRC /main.ts entry function will look like this:

Import {NestFactory} from '@nestjs/core' import {AppModule} from './app.module' import {NestFactory} from './app.module' async function bootstrap() { const app = await NestFactory.create(AppModule) await app.listen(3000) } bootstrap()Copy the code

run

Nest and Typeorm have been integrated through the above steps, and the project is started:

yarn run start
Copy the code

The browser then accesses localhost:3000/user and should see the following output:

{
    "id": 1."name": "user1"."password": "pass1"
}
Copy the code