---
# System prepended metadata

title: Nestjs - TypeORM Intergration
tags: [NestJS, typeORM]

---

###### tags: `NestJS` `typeORM`
# Nestjs - TypeORM Intergration
Nest提供`@nestjs/typeorm`套件來做TypeORM互動，因為TypeORM為TS中目前最成熟的ORM套件，他是用TS所寫的，所以能和Nest框架完美搭配。
以下會以MySQL為範例:
首先安裝套件:
```shell!
$ npm install --save @nestjs/typeorm typeorm mysql2
```
安裝完後，將`TypeOrmModule`引入到`AppModule`
```typescript!
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```
:::warning
Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.
:::
當上面完成後，TypeORM的`DataSource`和`EntityManager`物件就可以在整個專案使用，如下: 
```typescript!
import { DataSource } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(private dataSource: DataSource) {}
}
```
#### Repository pattern
TypeORM 支援repository design pattern,所以各個entity都有其repository,這些repository可以從database data source取得。
以下建立`User` Entity做示範：
```typescript!
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
```
為開始使用`User`Entity，我們將其放入app.module內的forRoot() method的entities陣列內。
```typescript!
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [User],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```
現在換看`UsersModule`:
```typescript!
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

** 以下方式與文件不同，而是將與資料庫互動的部分從service拆分出來為一個*.repository.ts，而後在service中注入repository進而拆分權責，以便維護。 **

/// 從這後開始修改

這個module使用`forFeature()`來定義是哪個repositories被註冊在目前的scope，有了這個，我們就可以將`UserRepository`使用`@InjectRepository()`注入到`UsersService`中，如下:
```typescript!
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  findAll(): Promise<User[]> {
    return this.usersRepository.find();
  }

  findOne(id: string): Promise<User> {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id: string): Promise<void> {
    await this.usersRepository.delete(id);
  }
}



```
如果你想要在外部的module使用此repository，你一樣必須要到module這裡把import的`TypeOrmModule.forFeature`再把他export:
```typescript!
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  exports: [TypeOrmModule]
})
export class UsersModule {}
```