NestJSでMySQLを使う


# 参考資料
https://docs.nestjs.com/techniques/database
https://qiita.com/Aurum64/items/f5962bd2a643447dbef9
https://typeorm.io/data-source
https://qiita.com/t-yama-3/items/fa2113fcabf84e0a20e6



## 使用技術
- Nest.js
- TypeORM@0.3
- MySQL


下記を実行してる状態です
nest new sample

## ライブラリインストール
```
npm install @nestjs/typeorm typeorm mysql2
```

## docker-composeでMySQLのコンテナを立ち上げ
```yml:docker-compose.yml
version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: mysql
    volumes:
      - ./mysql-data:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: test
      MYSQL_DATABASE: test
      MYSQL_USER: test
      MYSQL_PASSWORD: test
```

```
docker-compoes up -d
```

## MySQLでDBが作成されていることを確認
```
docker-compose exec mysql bash

> mysql -u test -p
> test # パスワードを入力する

> show databases;
> use test;
> show tables;
# テーブルがないことを確認する
```

## エンティティ作成
```
nest g resource user
```

```ts:src/user/entities/user.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

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

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}

```

## DataSource作成
```ts:data-source.ts
import { DataSource } from 'typeorm';
import { User } from './user/entities/user.entity';

export const AppDataSource = new DataSource({
  type: 'mysql',
  host: 'localhost',
  port: 3306,
  username: 'test',
  password: 'test',
  database: 'test',
  synchronize: true,
  entities: [User],
});
```

## DB接続

```ts:app.module.ts
import { AppDataSource } from './data-source';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';

@Module({
  imports: [TypeOrmModule.forRoot(AppDataSource.options), UserModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

## テーブルが作成されていることを確認
```
npm run start:dev
```
```
show tables;
describe uesr;
```

```mysql
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int          | NO   | PRI | NULL    | auto_increment |
| firstName | varchar(255) | NO   |     | NULL    |                |
| lastName  | varchar(255) | NO   |     | NULL    |                |
| isActive  | tinyint      | NO   |     | 1       |                |
+-----------+--------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)
```

# migration導入
```ts:data-source.ts
import { DataSource } from 'typeorm';
import { User } from './user/entities/user.entity'; // entityファイル

export const AppDataSource = new DataSource({
  type: 'mysql',
  host: 'localhost',
  port: 3306,
  username: 'test',
  password: 'test',
  database: 'test',
  synchronize: false, // 同期をオフにする
  logging: true,
  entities: [User],
  migrations: ['dist/migration/*.js'],
});
```

## エラーがあった場合
:::message
No changes in database schema were found - cannot generate a migration. To create a new empty migration use "typeorm migration:create" command
:::
上記のエラーがあった場合はschema:dropする

```
npm run migration:revert # マイグレーションのバージョンを戻す
npm run schema:drop
# もし、マイグレーションファイルがある場合は削除する

# 一応サーバーを立ち上げ直す
npm run start:dev
```

## マイグレーションファイル作成
```
npm run migration:generate --name=UserMigration

# 作れていることを確認する
npm run migration:show

# -> []になっていたらOK
```

## テーブル作成
```
npm run migration:run
```

☟
再度、MySQLでDBが作成されていることを確認する。
もしうまくいかない場合は、下記について調べてみると良いかもしれません。

- npmスクリプト
https://www.twilio.com/ja/blog/npm-scripts-jp
- マイグレーションの仕組み
- typeorm@0.3とtypeorm@0.2の違い
- typeorm@0.3 + nestjs