TypeOrm 查询隐藏列

837 阅读1分钟

前言

在做获取用户信息接口时,我们常常需要隐藏某些字段,TypeOrm 在 @Column装饰器中提供了 select: false选项,但这同时也带来了一个新问题,findOne 等方法是无法查询到隐藏列的,即使你设置了 select: true 也是无效。

正文

SysUserEntity 为例,代码如下:

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'

@Entity()
export class SysUserEntity {
    @PrimaryGeneratedColumn({ type: 'bigint' })
    id: string

    @Column()
    userName: string

    @Column({ select: false })
    password: string
    
    @Column()
    remark: string
}

此时应该使用 QueryBuilder 构建查询语句,以登录接口服务为例:

import { BadRequestException, Injectable } from '@nestjs/common'
import { JwtService } from '@nestjs/jwt'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository } from 'typeorm'
import { APP_MESSAGES } from '@/constants'
import { SysUserEntity } from '@/entities'
import { IDUtil, PasswordUtil } from '@/utils'
import { LoginDTO } from './auth.dto'

@Injectable()
export class AuthService {
    constructor(
        @InjectRepository(SysUserEntity)
        private userModel: Repository<SysUserEntity>,
        private jwtService: JwtService
    ) {}
    
    async handleLogin(dto: LoginDTO) {
        const { userName, password } = dto
        const user = await this.userModel
            .createQueryBuilder('user')
            .select(['user'])
            .addSelect('user.password')
            .where({ userName })
            .getOne()

        if (user) {
            const isMatch = PasswordUtil.compare(password, user.password)
            const tokenId = IDUtil.randomID()

            if (isMatch) {
                return this.jwtService.sign({ userName, sub: tokenId })
            }
            throw new BadRequestException(APP_MESSAGES.ACCOUNT_OR_PASSWORD_ERROR)
        }
        throw new BadRequestException(APP_MESSAGES.USER_NOT_EXIST)  
    }
}

总结

当不涉及隐藏列查询时,用 findOne 等方法查询即可;当需要查询隐藏列时,请使用 QueryBuilderaddSelect