如何在NestJS+TypeORM+PostgreSQL中设置默认查询排序为id降序
如何在NestJS+TypeORM+PostgreSQL中设置默认查询排序为id降序
嘿,这个需求太实用了!不用每次写查询都手动加排序确实能省不少事儿,在TypeORM里有几种靠谱的方法能实现,咱一个个说清楚:
方法一:单个实体级别设置默认排序
这是最直接的方式,直接在实体类上通过@Entity装饰器的配置项指定默认排序规则。这样每次查询这个实体时,TypeORM都会自动加上ORDER BY id DESC,完全不用你手动写。
举个例子,比如你的User实体:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; // 这里通过order属性设置默认排序规则 @Entity({ order: { id: 'DESC' } }) export class User { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column({ default: () => 'CURRENT_TIMESTAMP' }) updatedAt: Date; }
之后不管你调用userRepository.find()还是userRepository.findOne(),默认都会按id倒序返回结果。如果某一次查询需要自定义排序,直接传order参数就能覆盖这个默认设置,比如:
// 这次查询会按updatedAt降序,覆盖默认的id排序 const users = await this.userRepository.find({ order: { updatedAt: 'DESC' } });
方法二:全局自定义BaseRepository(适合多实体统一配置)
如果你的项目里有很多实体都需要默认按id降序,一个个给实体加配置太麻烦,那可以自定义一个基础Repository类,让所有实体的Repository都继承它,统一处理默认排序。
第一步:创建BaseRepository基类
import { Repository, SelectQueryBuilder } from 'typeorm'; export class BaseRepository<T> extends Repository<T> { // 重写find方法,自动添加默认排序(如果没传自定义order的话) async find(options: any = {}) { if (!options.order) { options.order = { id: 'DESC' }; } return super.find(options); } // 处理findOne的两种调用方式:传id或者传查询条件 async findOne(options: any = {}) { if (typeof options === 'number' || typeof options === 'string') { return super.findOne(options); } if (!options.order) { options.order = { id: 'DESC' }; } return super.findOne(options); } // 重写createQueryBuilder,默认添加排序规则 createQueryBuilder(alias?: string, queryRunner?: any): SelectQueryBuilder<T> { const queryBuilder = super.createQueryBuilder(alias, queryRunner); // 结合别名避免字段冲突,适配不同实体 queryBuilder.orderBy(`${alias || this.metadata.tableName}.id`, 'DESC'); return queryBuilder; } }
第二步:在NestJS中使用自定义Repository
在你的模块里,通过TypeOrmModule.forFeature()指定每个实体使用这个BaseRepository(以UserModule为例):
import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from './user.entity'; import { BaseRepository } from '../common/base.repository'; import { UserService } from './user.service'; @Module({ imports: [ TypeOrmModule.forFeature([ { name: User.name, // 扩展默认Repository为我们的BaseRepository repository: (dataSource) => dataSource.getRepository(User).extend(BaseRepository), }, ]), ], providers: [UserService], exports: [TypeOrmModule], }) export class UserModule {}
这样之后,所有继承BaseRepository的实体查询都会自动应用id降序的默认排序,同样,手动传order参数会优先于默认规则。
一些小提醒
- 如果你的实体id是UUID字符串类型,这个方法同样适用,TypeORM会正确处理字符串类型的排序。
- 关联查询中,如果你希望关联的实体也应用默认排序,可以在关联装饰器里单独设置,比如
@OneToMany(() => Post, post => post.user, { order: { id: 'DESC' } })。
备注:内容来源于stack exchange,提问作者damian
相关产品推荐
相关产品推荐

