用 NestJS 从零开发一个完整的小项目:图书管理系统(第三阶段:接入 MySQL + TypeORM)

目标:

把现在的:

复制代码
复制代码
private books = []

变成:

复制代码
复制代码
Controller
   ↓
Service
   ↓
TypeORM
   ↓
MySQL

真正实现数据持久化。


第一步:准备 MySQL

先确认你的电脑有 MySQL。

查看版本:

复制代码
复制代码
mysql --version

例如:

复制代码
复制代码
mysql  Ver 8.0.xx

如果没有安装,可以安装:

  • MySQL 8.x(推荐)
  • MariaDB(也可以)

创建数据库

登录:

复制代码
复制代码
mysql -u root -p

创建数据库:

复制代码
复制代码
CREATE DATABASE nest_book;

查看:

复制代码
复制代码
SHOW DATABASES;

应该能看到:

复制代码
复制代码
nest_book

第二步:安装 TypeORM

Nest 官方推荐 ORM 是:

TypeORM

安装:

复制代码
复制代码
pnpm add @nestjs/typeorm typeorm mysql2

作用:

作用
@nestjs/typeorm Nest 集成
typeorm ORM 核心
mysql2 MySQL 驱动

第三步:配置数据库连接

修改:

复制代码
复制代码
src/app.module.ts

导入:

复制代码
复制代码
import { TypeOrmModule } from '@nestjs/typeorm';

修改:

复制代码
复制代码
@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',

      host: 'localhost',

      port: 3306,

      username: 'root',

      password: '123456',

      database: 'nest_book',

      autoLoadEntities: true,

      synchronize: true,
    }),

    BooksModule,
  ],
})
export class AppModule {}

配置解释

synchronize

复制代码
复制代码
synchronize: true

开发环境:

复制代码
复制代码
实体变化
 ↓
自动修改表结构

方便开发。

生产环境必须:

复制代码
复制代码
synchronize: false

autoLoadEntities

复制代码
复制代码
autoLoadEntities: true

自动加载所有 Entity。

不用手动注册。


第四步:创建 Entity

打开:

复制代码
复制代码
src/books/entities/book.entity.ts

修改:

复制代码
复制代码
import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
} from 'typeorm';

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

  @Column()
  name: string;

  @Column()
  author: string;
}

理解

Entity

复制代码
复制代码
@Entity()

表示:

复制代码
复制代码
Book
 ↓
映射成数据库表

主键

复制代码
复制代码
@PrimaryGeneratedColumn()
id: number;

对应:

复制代码
复制代码
id INT AUTO_INCREMENT PRIMARY KEY

字段

复制代码
复制代码
@Column()
name: string;

对应:

复制代码
复制代码
name VARCHAR(255)

第五步:注册 Entity

修改:

复制代码
复制代码
src/books/books.module.ts

导入:

复制代码
复制代码
import { TypeOrmModule } from '@nestjs/typeorm';
import { Book } from './entities/book.entity';

修改:

复制代码
复制代码
@Module({
  imports: [
    TypeOrmModule.forFeature([Book]),
  ],

  controllers: [BooksController],

  providers: [BooksService],
})
export class BooksModule {}

为什么?

Nest DI 容器需要知道:

复制代码
复制代码
Book Repository

从哪里来。

所以:

复制代码
复制代码
TypeOrmModule.forFeature([Book])

负责注册 Repository。


第六步:注入 Repository

修改:

复制代码
复制代码
books.service.ts

导入:

复制代码
复制代码
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Book } from './entities/book.entity';

构造函数:

复制代码
复制代码
constructor(
  @InjectRepository(Book)
  private readonly bookRepository: Repository<Book>,
) {}

现在:

复制代码
复制代码
bookRepository

相当于:

复制代码
复制代码
SELECT *
INSERT
UPDATE
DELETE

操作器。


第七步:实现查询全部

修改:

复制代码
复制代码
findAll() {
  return this.bookRepository.find();
}

测试:

复制代码
复制代码
GET /books

如果表为空:

复制代码
复制代码
[]

第八步:实现新增

修改:

复制代码
复制代码
async create(createBookDto: CreateBookDto) {
  const book =
    this.bookRepository.create(createBookDto);

  return await this.bookRepository.save(book);
}

create

只是创建对象:

复制代码
复制代码
const book =
this.bookRepository.create(dto);

内存中:

复制代码
复制代码
{
  name:'NestJS',
  author:'Tom'
}

save

真正写数据库:

复制代码
复制代码
await this.bookRepository.save(book);

执行:

复制代码
复制代码
INSERT INTO book ...

测试:

复制代码
复制代码
POST /books
复制代码
复制代码
{
  "name":"NestJS实战",
  "author":"Tom"
}

返回:

复制代码
复制代码
{
  "id":1,
  "name":"NestJS实战",
  "author":"Tom"
}

查看数据库:

复制代码
复制代码
SELECT * FROM book;

结果:

id name author
1 NestJS实战 Tom

第九步:实现查询单个

复制代码
复制代码
findOne(id: number) {
  return this.bookRepository.findOne({
    where: { id },
  });
}

测试:

复制代码
复制代码
GET /books/1

返回:

复制代码
复制代码
{
  "id":1,
  "name":"NestJS实战",
  "author":"Tom"
}

第十步:实现删除

复制代码
复制代码
remove(id: number) {
  return this.bookRepository.delete(id);
}

测试:

复制代码
复制代码
DELETE /books/1

返回:

复制代码
复制代码
{
  "affected":1
}

第十一步:实现更新

复制代码
复制代码
async update(
  id: number,
  updateBookDto: UpdateBookDto,
) {
  await this.bookRepository.update(
    id,
    updateBookDto,
  );

  return this.findOne(id);
}

测试:

复制代码
复制代码
PATCH /books/1
复制代码
复制代码
{
  "author":"Jerry"
}

再次查询:

复制代码
复制代码
GET /books/1

返回:

复制代码
复制代码
{
  "id":1,
  "name":"NestJS实战",
  "author":"Jerry"
}

到这里,你已经掌握了:

✅ Entity

✅ Repository

✅ MySQL连接

✅ TypeORM集成

✅ CRUD持久化

✅ DI注入Repository

现在项目已经从"玩具项目"升级成"真实后端项目"。