文山壮族苗族自治州网站建设_网站建设公司_漏洞修复_seo优化
2026/1/10 16:32:51 网站建设 项目流程

文章目录

  • 前言
      • 1. 最核心的几个装饰器(必须记住)
      • 2. NestJS 提供的 TypeORM 集成工具(@nestjs/typeorm 包)
      • 3. 常用 Repository 操作速查表
      • 4. 目前主流推荐的几种写法风格(2025~2026)
      • 5. 小Tips(非常实用)
    • 扩展🚀🚀🚀
      • 1. 迁移的核心概念(为什么要用迁移?)
      • 2. 推荐的项目结构(2025~2026 最常见布局)
      • 3. 现代推荐配置方式(2025-2026主流)
      • 4. 常用 CLI 命令(package.json 推荐配置)
      • 5. 迁移文件长什么样?(自动生成 vs 手动)
      • 6. 2025-2026 最佳实践总结表
      • 7. 快速诊断常见问题(2025-2026 仍然高频)

前言

NestJS中使用TypeORM是目前最主流、最成熟的数据库解决方案之一(2026年依然如此),TypeORM 是 Node.js 生态里最强大的 TypeScript 原生 ORM。

NestJS + TypeORM 开发中最常用的工具装饰器模式实用技巧

1. 最核心的几个装饰器(必须记住)

装饰器作用常用位置备注
@Entity()声明这是一个数据库表实体class可加参数:{ name: ‘custom_table’ }
@PrimaryGeneratedColumn()自增主键(推荐)property默认使用 increment
@PrimaryColumn()自定义主键(uuid、手动id等)property
@Column()普通字段property支持几乎所有类型参数
@CreateDateColumn()自动创建时间property
@UpdateDateColumn()自动更新时间property
@DeleteDateColumn()软删除时间(配合软删除使用)property
@ManyToOne()/@OneToMany()多对一 / 一对多关系property最常用关系
@OneToOne()一对一关系property常用于用户-资料、商品-详情等
@ManyToMany()+@JoinTable()多对多关系(必须在一方写@JoinTable()property非常常见:标签、角色、权限等

2. NestJS 提供的 TypeORM 集成工具(@nestjs/typeorm 包)

工具/方法用途使用位置推荐程度
TypeOrmModule.forRoot()全局数据库连接(推荐使用异步配置)AppModule★★★★★
TypeOrmModule.forRootAsync()异步配置(推荐!配合 ConfigModule)AppModule★★★★★
TypeOrmModule.forFeature([Entity])注册特定实体,让模块内可注入 RepositoryFeatureModule★★★★★
@InjectRepository(Entity)注入某个实体的 RepositoryService★★★★★
getRepositoryToken(Entity)手动提供自定义 Repository 时使用自定义 provider★★★

目前(2025~2026)最推荐的全局配置写法

// app.module.ts@Module({imports:[ConfigModule.forRoot({isGlobal:true}),TypeOrmModule.forRootAsync({imports:[ConfigModule],inject:[ConfigService],useFactory:(config:ConfigService)=>({type:'mysql',// 或 postgres、sqlite、mongodb...host:config.get('DB_HOST'),port:+config.get('DB_PORT'),username:config.get('DB_USERNAME'),password:config.get('DB_PASSWORD'),database:config.get('DB_DATABASE'),entities:[__dirname+'/**/*.entity.{ts,js}'],synchronize:config.get('NODE_ENV')!=='production',// 生产千万别开!logging:config.get('NODE_ENV')==='development'?['query','error']:false,timezone:'+08:00',// 很重要!中文项目建议加上}),}),// 其他模块...],})exportclassAppModule{}

3. 常用 Repository 操作速查表

// 最常用的几种写法(都在 service 里)// 1. 基本 CRUDawaitthis.repo.find()// 全部awaitthis.repo.findOneBy({id})// 找一条(推荐)awaitthis.repo.findBy({status:1})// 条件查找多条awaitthis.repo.save(entity)// 新增/修改(智能判断)awaitthis.repo.remove(entity)// 删除实体awaitthis.repo.softRemove(entity)// 软删除(需有 deletedAt 字段)// 2. 带关联查询(最常用写法)awaitthis.repo.find({where:{id},relations:['user','user.profile','tags'],// 嵌套也支持loadRelationIds:true,// 只加载 id(性能优化)})// 3. QueryBuilder(复杂查询必备)this.repo.createQueryBuilder('post').leftJoinAndSelect('post.user','user').leftJoinAndSelect('post.tags','tag').where('post.status = :status',{status:1}).andWhere('tag.name = :tagName',{tagName:'nestjs'}).orderBy('post.createdAt','DESC').skip(0).take(10).getMany()// 4. 事务(非常重要!)awaitthis.dataSource.transaction(asyncmanager=>{awaitmanager.save(User,user);awaitmanager.save(Profile,profile);// ...更多操作})

4. 目前主流推荐的几种写法风格(2025~2026)

风格优点缺点推荐场景
Active Record写起来最少代码实体类变得臃肿,耦合严重小型项目/快速原型
Repository模式最符合 NestJS 哲学,解耦最好代码量稍多中大型项目(最推荐)
QueryService统一查询入口,适合复杂查询学习成本稍高中后台系统、B 端系统
Custom Repository最高自由度,可封装复杂业务逻辑维护成本较高业务非常复杂时
AbstractService统一 CRUD 基类,减少重复代码过度抽象容易翻车团队规范强、实体非常多时

2025~2026 最主流推荐Repository 模式 + QueryBuilder + 事务的组合拳

5. 小Tips(非常实用)

  • 生产环境永远关闭synchronize: true
  • 强烈建议使用迁移(migrations)
  • 关联查询多的时候优先考虑loadRelationIds+ 二次查询
  • 性能敏感接口尽量少用relations,改用QueryBuilder精确控制
  • 软删除记得用withDeleted才能查到已删除数据
  • 大项目建议使用typeorm-extension或自己封装BaseRepository

扩展🚀🚀🚀

TypeORM Migrations是目前(2026年1月)在NestJS项目中最推荐的数据库模式演进方式,尤其是在生产环境中绝对不能使用synchronize: true

下面是目前最完整、最实用的 TypeORM 迁移指南(基于 TypeORM 0.3.x ~ 最新版本 + NestJS 10/11 生态):

1. 迁移的核心概念(为什么要用迁移?)

方式开发阶段生产环境数据安全性版本控制团队协作推荐程度 2026
synchronize: true非常方便极度危险经常丢数据灾难★☆☆☆☆
手动写 migration很安全安全最高很好★★★★☆
自动生成 migration方便+安全安全高(需审查)优秀★★★★★

2025-2026 主流结论开发阶段可以用 synchronize,生产必须关闭 + 使用迁移
最推荐的折中方案:自动生成 + 人工审查(90%以上的团队都这么做)

2. 推荐的项目结构(2025~2026 最常见布局)

src/ ├── database/ # 独立数据库相关 │ ├──>3. 现代推荐配置方式(2025-2026主流)

创建src/database/data-source.ts(非常重要!CLI 要用它)

// src/database/data-source.tsimport{DataSource}from'typeorm';import*asdotenvfrom'dotenv';dotenv.config();exportconstAppDataSource=newDataSource({type:'postgres',// 或 mysql, mariadb, sqlite...host:process.env.DB_HOST||'localhost',port:Number(process.env.DB_PORT)||5432,username:process.env.DB_USERNAME||'postgres',password:process.env.DB_PASSWORD||'postgres',database:process.env.DB_NAME||'mydb',// 重要:生产一定用 js,已编译后的文件entities:['dist/**/*.entity{.ts,.js}'],migrations:['dist/database/migrations/*{.ts,.js}'],// 强烈建议:synchronize:false,// 生产必须 false!logging:process.env.NODE_ENV==='development',migrationsRun:false,// 不要在应用启动时自动跑(推荐手动或 pipeline 控制)// 可选但非常推荐(尤其 postgres/mysql)extra:{max:30,// 连接池大小connectionTimeoutMillis:2000,},});// 方便开发时直接用 ts-node 执行exportdefaultAppDataSource;

4. 常用 CLI 命令(package.json 推荐配置)

"scripts":{"typeorm":"ts-node ./node_modules/typeorm/cli.js --dataSource src/database/data-source.ts","typeorm:prod":"node --require tsconfig-paths/register ./node_modules/typeorm/cli.js --dataSource dist/database/data-source.js","migration:generate":"npm run typeorm migration:generate src/database/migrations/$npm_config_name","migration:create":"npm run typeorm migration:create src/database/migrations/$npm_config_name","migration:run":"npm run typeorm migration:run","migration:revert":"npm run typeorm migration:revert","migration:run:prod":"npm run typeorm:prod migration:run"}

使用方式示例

# 生成迁移(推荐!)npmrun migration:generate --name=AddUserLastLogin# 空迁移(需要自己写复杂逻辑时)npmrun migration:create --name=ComplexDataMigration# 运行所有待执行迁移npmrun migration:run# 回滚最近的一次迁移npmrun migration:revert

5. 迁移文件长什么样?(自动生成 vs 手动)

自动生成的典型样子(最常见):

import{MigrationInterface,QueryRunner}from"typeorm";exportclassAddUserLastLogin1723456789012implementsMigrationInterface{publicasyncup(queryRunner:QueryRunner):Promise<void>{awaitqueryRunner.query(`ALTER TABLE "users" ADD "lastLogin" timestamp`);}publicasyncdown(queryRunner:QueryRunner):Promise<void>{awaitqueryRunner.query(`ALTER TABLE "users" DROP COLUMN "lastLogin"`);}}

手动迁移常见场景(自动生成做不到或不安全时):

  • 大批量数据更新/转换
  • 复杂列类型转换(jsonb → 拆分成多列)
  • 表重命名 + 数据迁移
  • 添加/删除外键约束(带级联)
  • 插入/更新初始数据(部分团队会放在 migration 里)

6. 2025-2026 最佳实践总结表

实践推荐度说明
生产环境永远synchronize: false★★★★★否则极易丢数据
使用单独的data-source.ts★★★★★CLI 和应用共用配置,避免重复
migration 文件放dist/里运行★★★★☆部署后才能执行(生产必须编译后的 js)
每次生成后必须人工 review★★★★★自动生成有时会产生危险操作(如 drop column)
迁移 + CI/CD pipeline 执行★★★★☆推荐在 deploy 时自动跑 migration:run
不要在 migration 里依赖服务★★★★☆migration 类不能使用 NestJS DI(独立执行)
复杂数据迁移考虑使用typeorm-extensiondb:seeders★★★☆☆分离 schema 变更和数据填充
团队约定迁移命名规范★★★★☆e.g.AddUserProfileFields_20250110
永远保留down方法完整可执行★★★★☆便于测试回滚和环境重建

7. 快速诊断常见问题(2025-2026 仍然高频)

问题原因解决方式
生成迁移时把所有表都重新生成了数据库和实体不匹配 / 命名大小写检查数据库名、表名大小写,清理typeorm_metadata
迁移运行时报relation does not exist迁移顺序错乱删除migrations表记录 + 重新跑
生产环境迁移没执行没编译成 js / 路径错误使用typeorm:prod脚本 + 检查dist路径
Cannot find entityentities 路径不对确认dist/**/*.entity.js

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询