三、NestJS 开发实战文档-->集成 MySQL(TypeORM)

NestJS 集成 MySQL(TypeORM)完整配置与使用指南

一、核心依赖说明

依赖名称 版本参考 功能描述
@nestjs/typeorm ^11.0.0 NestJS 与 TypeORM 的官方集成包,提供模块化支持
mysql2 ^3.14.0 MySQL 数据库驱动,用于建立数据库连接
typeorm ^0.3.22 TypeORM 核心库,提供 ORM 数据操作能力

依赖安装命令

bash 复制代码
# 生产环境依赖
npm install @nestjs/typeorm mysql2 typeorm
# 若需类型提示(可选,TypeScript 项目推荐)
npm install @types/mysql --save-dev

二、全局 MySQL 模块配置

2.1 配置文件(src/db/mysql/mysql.module.ts)

采用 @Global() 装饰器实现全局模块,无需在各业务模块中重复导入,统一管理数据库连接配置。

typescript 复制代码
import { Global, Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
// 导入实体类(可根据项目实际情况调整)
import { User } from '../../entities/user/user.entity';
import { UserLogin } from '../../entities/user/user-login.entity';
import { UserBase } from '../../entities/user/user-base.entity';

@Global() // 标记为全局模块,所有业务模块可直接使用,无需重复导入
@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql', // 数据库类型(固定为 mysql,对应 mysql2 驱动)
      host: 'localhost', // 数据库主机地址(生产环境替换为实际服务器地址)
      port: 3306, // MySQL 默认端口
      username: 'root', // 数据库用户名
      password: 'your_mysql_password', // 数据库密码(建议通过环境变量配置,避免硬编码)
      database: 'sl-sys', // 要连接的数据库名(需提前手动创建)
      timezone: 'Z', // 时区配置(Z 表示 UTC 时区,也可配置为 '+08:00' 对应东八区)
      entities: [User, UserLogin, UserBase], // 显式注册实体类
      autoLoadEntities: true, // 自动加载项目中所有实体类(无需手动全部注册,简化配置)
      synchronize: true, // 开发环境:自动同步实体类与数据库表结构(新增/修改字段自动同步)
      // logging: true, // 可选:开启 SQL 日志打印,便于开发调试
      // charset: 'utf8mb4', // 可选:支持 emoji 等特殊字符,推荐配置
    }),
  ],
  // 无需导出,全局模块的配置会自动生效
})
export class MysqlModule {}

2.2 关键配置项说明

配置项 取值/说明
type 固定为 mysql,指定数据库类型
entities 显式声明需要加载的实体类,与 autoLoadEntities: true 配合使用,双重保障
autoLoadEntities 开启后自动扫描项目中的实体类,无需手动逐个添加,简化维护
synchronize 开发环境设为 true(自动同步表结构),生产环境必须设为 false(避免数据丢失)
timezone 时区配置,推荐使用 '+08:00'(东八区),避免时间存储偏差

三、实体类设计(数据库表映射)

3.1 核心实体示例(src/entities/user/user.entity.ts)

使用 TypeORM 装饰器实现实体类与 MySQL 表的映射,支持字段属性、关联关系配置。

typescript 复制代码
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from 'typeorm';
import { UserBase } from './user-base.entity';

// 映射到 MySQL 中的 `user` 表
@Entity('user') 
export class User {
  // 自增主键(对应 MySQL 的 INT AUTO_INCREMENT)
  @PrimaryGeneratedColumn({ comment: '用户自增主键' })
  user_id: string; // 字段类型可根据实际需求改为 number

  // 普通字段:姓名(varchar 类型,长度 50,非空,带注释)
  @Column({ type: 'varchar', name: 'name', comment: '用户姓名', length: 50, nullable: false })
  name: string;

  // 密码字段:查询时默认不返回(select: false),避免密码泄露
  @Column({ type: 'varchar', name: 'password', comment: '用户密码(加密存储)', length: 100, select: false })
  password: string;

  // 一对一关联:User 关联 UserBase(通过 user_id 外键)
  @OneToOne(() => UserBase) // 关联的目标实体类
  @JoinColumn({ name: 'user_id', referencedColumnName: 'user_id' }) // 外键配置(当前表 user_id 关联 UserBase 的 user_id)
  user_base: UserBase; // 关联的实体对象
}

3.2 装饰器核心说明

装饰器 功能描述
@Entity('tableName') 标记为实体类,指定映射的 MySQL 表名
@PrimaryGeneratedColumn 定义自增主键,默认对应 MySQL 的 INT AUTO_INCREMENT
@Column 定义普通数据库字段,支持 type、name、length、nullable 等属性配置
@OneToOne 定义一对一关联关系,需配合 @JoinColumn 指定外键
@JoinColumn 配置外键关联,name 为当前表的外键字段,referencedColumnName 为目标表的关联字段
select: false 查询该实体时,默认不返回该字段(如密码字段),提升安全性

四、根模块注册(app.module.ts)

在项目根模块中导入全局 MySQL 模块,使其在整个项目中生效。

typescript 复制代码
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { MysqlModule } from './db/mysql/mysql.module'; // 导入全局 MySQL 模块
import { UserModule } from './service/user/user.module';
import { AuthModule } from './service/auth/auth.module';

@Module({
  imports: [
    // 环境变量配置(全局生效)
    ConfigModule.forRoot({ isGlobal: true }),
    MysqlModule, // 导入 MySQL 全局模块,所有业务模块可直接使用数据库操作
    UserModule, // 业务模块
    AuthModule, // 认证模块
    // 其他业务模块...
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

五、数据库操作(服务层实现)

5.1 核心服务示例(src/service/user/user.service.ts)

通过 @InjectRepository 注入 TypeORM Repository 对象,实现数据库的查询、新增、修改、删除等操作。

typescript 复制代码
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from '../../entities/user/user.entity';

@Injectable()
export class UserService {
  // 注入 User 实体的 Repository(数据访问对象)
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
  ) {}

  /**
   * 根据用户ID查询用户信息(连表查询 User 与 UserBase)
   * @param user_id 用户ID
   * @returns 用户完整信息(包含 user_base 关联数据)
   */
  async getUserInfo(user_id: string) {
    return await this.userRepository
      .createQueryBuilder('user') // 别名:user
      .leftJoinAndSelect('user.user_base', 'user_base') // 左连接 UserBase,别名:user_base
      .where('user.user_id = :id', { id: user_id }) // 查询条件
      .getOne(); // 获取单条数据(若无数据返回 null)
  }

  /**
   * 新增用户
   * @param userData 用户信息
   * @returns 新增后的用户数据
   */
  async createUser(userData: Partial<User>) {
    const user = this.userRepository.create(userData); // 创建实体实例
    return await this.userRepository.save(user); // 保存到数据库
  }

  /**
   * 修改用户信息
   * @param user_id 用户ID
   * @param updateData 要修改的字段
   * @returns 修改结果
   */
  async updateUser(user_id: string, updateData: Partial<User>) {
    return await this.userRepository
      .createQueryBuilder()
      .update(User)
      .set(updateData)
      .where('user_id = :id', { id: user_id })
      .execute();
  }

  /**
   * 删除用户
   * @param user_id 用户ID
   * @returns 删除结果
   */
  async deleteUser(user_id: string) {
    return await this.userRepository
      .createQueryBuilder()
      .delete()
      .from(User)
      .where('user_id = :id', { id: user_id })
      .execute();
  }
}

5.2 核心操作说明

  1. Repository 注入 :通过 @InjectRepository(实体类) 注入对应的数据访问对象,提供基础 CRUD 操作
  2. 查询构建器createQueryBuilder 提供灵活的 SQL 构建能力,支持连表、条件查询、分页等复杂操作
  3. 基础操作
    • create:创建实体实例(不直接入库)
    • save:保存实体(新增/修改,根据主键是否存在自动判断)
    • update/delete:批量更新/删除,通过 execute() 执行操作

六、项目目录结构

采用分层设计,职责清晰,便于维护和扩展。

复制代码
src/
├── db/                      # 数据库配置目录
│   └── mysql/
│       └── mysql.module.ts  # MySQL 全局配置模块
├── entities/                # 实体类目录(对应数据库表)
│   └── user/                # 用户相关实体
│       ├── user.entity.ts   # User 实体(映射 user 表)
│       ├── user-base.entity.ts # UserBase 实体(映射 user_base 表)
│       └── user-login.entity.ts # UserLogin 实体(映射 user_login 表)
├── service/                 # 业务服务目录
│   └── user/                # 用户业务模块
│       ├── user.service.ts  # 用户业务逻辑 + 数据库操作
│       ├── user.controller.ts # 用户接口控制器
│       └── user.module.ts   # 用户模块配置
│   └── auth/                # 认证业务模块
├── app.module.ts            # 项目根模块(注册全局模块 + 业务模块)
└── main.ts                  # 项目入口文件

七、核心特点总结

  1. 全局模块化MysqlModule 标记为全局模块,所有业务模块无需重复导入,简化配置
  2. TypeORM 强集成 :通过 TypeOrmModule 快速实现数据库连接,支持实体映射、查询构建器等强大功能
  3. 安全可靠 :密码字段默认不返回(select: false),开发/生产环境配置隔离(synchronize 开关)
  4. 易于维护:实体类与数据库表一一映射,目录结构清晰,业务逻辑与数据操作分离
  5. 功能灵活:支持一对一关联查询、动态 SQL 构建,满足复杂业务场景需求

八、生产环境优化建议

  1. 环境变量配置 :将数据库主机、用户名、密码等配置通过 .env 文件管理,避免硬编码

    typescript 复制代码
    // 优化后的 mysql.module.ts 配置(读取环境变量)
    TypeOrmModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        type: 'mysql',
        host: configService.get('DB_HOST'),
        port: configService.get('DB_PORT'),
        username: configService.get('DB_USERNAME'),
        password: configService.get('DB_PASSWORD'),
        database: configService.get('DB_DATABASE'),
        entities: [User, UserLogin, UserBase],
        autoLoadEntities: true,
        synchronize: false, // 生产环境禁用自动同步
        logging: false, // 生产环境关闭 SQL 日志
        charset: 'utf8mb4',
      }),
    })
  2. 关闭 synchronize :生产环境必须设为 false,通过 TypeORM 迁移工具(typeorm migration:run)管理表结构变更

  3. 连接池配置 :添加连接池配置,提升数据库连接复用率和性能

    typescript 复制代码
    TypeOrmModule.forRoot({
      // 其他配置...
      extra: {
        connectionLimit: 10, // 连接池最大连接数
      },
    })
  4. 实体索引 :为常用查询字段添加索引,提升查询性能

    typescript 复制代码
    @Column({ type: 'varchar', name: 'name', comment: '用户姓名', length: 50, nullable: false, unique: true })
    // 或手动添加索引
    @Index('idx_user_name', ['name'])
相关推荐
dreams_dream2 小时前
Element UI菜单折叠后的el-menu-item属性无法修改问题解决
前端·vue
duanyuehuan2 小时前
vueRouter重置路由
前端·javascript·vue.js
码农水水2 小时前
大疆Java面试被问:Spring事务的传播行为详解
java·数据库·spring
Misnearch2 小时前
npm包-serve包使用
前端·npm·node.js
逍遥德2 小时前
mysql-8.4.7-winx64.zip 安装/运行
数据库·mysql
IT_陈寒2 小时前
React 18 性能优化实战:5个被低估的Hooks用法让你的应用快30%
前端·人工智能·后端
lkbhua莱克瓦242 小时前
基础-约束
android·开发语言·数据库·笔记·sql·mysql·约束
falldeep2 小时前
LeetCode高频SQL50题总结
数据结构·数据库·sql·算法·leetcode·职场和发展
万邦科技Lafite2 小时前
淘宝开放API获取订单信息教程(2025年最新版)
java·开发语言·数据库·人工智能·python·开放api·电商开放平台