前言
在做获取用户信息接口时,我们常常需要隐藏某些字段,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 等方法查询即可;当需要查询隐藏列时,请使用 QueryBuilder 和 addSelect。