BaseEntity 实体基类使用文档
概述
BaseEntity 是一个抽象的实体基类,为所有数据库实体提供通用的基础字段和功能。它基于 TypeORM 构建,包含了常见的 CRUD 操作所需的时间戳、用户信息和软删除字段。
基础使用
继承 BaseEntity
typescript
import { Entity } from 'typeorm'
import { BaseEntity, MyEntity } from '@/common/entity/BaseEntity'
@MyEntity('user')
export class User extends BaseEntity {
// 自定义字段
name: string
email: string
age: number
}字段说明
BaseEntity 包含以下基础字段:
| 字段名 | 类型 | 描述 | 数据库列名 |
|---|---|---|---|
| id | string (bigint) | 主键ID | id |
| createTime | string | 创建时间 | create_time |
| createUser | string | 创建人 | create_user |
| updateTime | string | 更新时间 | update_time |
| updateUser | string | 更新人 | update_user |
| isDelete | BoolNum | 软删除标识 | is_delete |
API 参考
装饰器函数
MyEntity(name: string | EntityOptions, options?: EntityOptions)
自定义实体装饰器,自动转换表名为下划线格式。
typescript
// 基础用法
@MyEntity('user_info')
export class UserInfo extends BaseEntity {}
// 带选项用法
@MyEntity('user_profile', {
orderBy: { createTime: 'DESC' }
})
export class UserProfile extends BaseEntity {}BaseColumn(config: ColumnOptions)
增强版的 Column 装饰器,支持自动命名转换和字符串截断。
typescript
@BaseColumn({
length: 100,
comment: '用户名',
overLengthCut: true // 超长自动截断
})
name: string
@BaseColumn({
type: 'text',
comment: '用户描述'
})
description: stringDbUnique(target, propertyKey)
数据库唯一约束装饰器,在保存时自动校验唯一性。
typescript
@BaseColumn({ length: 50 })
@DbUnique
email: string
@BaseColumn({ length: 20 })
@DbUnique
phone: string工具函数
boolNumColumn(title: string, name: string, defaultValue?, options?)
生成布尔数字类型的列配置。
typescript
// 使用示例
@BaseColumn(boolNumColumn('激活状态', 'is_active', BoolNum.Yes))
isActive: BoolNum
@BaseColumn(boolNumColumn('管理员', 'is_admin', BoolNum.No))
isAdmin: BoolNumoverLengthCut(value: string, maxLength: string | number)
字符串超长截断工具函数。
typescript
const result = overLengthCut('这是一个很长的字符串', 10)
// 结果: '这是一个...'实例方法
assignOwn(obj: any)
安全的对象属性赋值,只保留实体中存在的字段。
typescript
const user = new User()
const userData = {
name: '张三',
email: 'zhangsan@example.com',
extraField: '不会被赋值的额外字段'
}
user.assignOwn(userData)
// 只会赋值 name 和 email 字段完整示例
用户实体示例
typescript
import { Entity, Column } from 'typeorm'
import { BaseEntity, MyEntity, BaseColumn, DbUnique, boolNumColumn } from '@/common/entity/BaseEntity'
import { BoolNum } from '@/common/type/base'
@MyEntity('sys_user')
export class SysUser extends BaseEntity {
@BaseColumn({
length: 50,
comment: '用户名',
overLengthCut: true
})
@DbUnique
username: string
@BaseColumn({
length: 100,
comment: '邮箱地址'
})
@DbUnique
email: string
@BaseColumn({
length: 50,
comment: '手机号码'
})
phone: string
@BaseColumn({
type: 'text',
comment: '用户简介'
})
bio: string
@BaseColumn(boolNumColumn('账户状态', 'status', BoolNum.Yes))
status: BoolNum
@BaseColumn({
type: 'int',
comment: '年龄'
})
age: number
}在 Service 中使用
typescript
import { Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository } from 'typeorm'
import { SysUser } from './entities/sys-user.entity'
@Injectable()
export class UserService {
constructor(
@InjectRepository(SysUser)
private readonly userRepository: Repository<SysUser>,
) {}
async createUser(userData: Partial<SysUser>): Promise<SysUser> {
const user = new SysUser()
user.assignOwn(userData) // 安全赋值
user.createUser = 'admin' // 设置创建人
// createTime 会自动设置为当前时间
return await this.userRepository.save(user)
}
async updateUser(id: string, updateData: Partial<SysUser>): Promise<SysUser> {
const user = await this.userRepository.findOne({ where: { id } })
if (!user) {
throw new Error('用户不存在')
}
user.assignOwn(updateData) // 安全更新
user.updateUser = 'admin' // 设置更新人
// updateTime 会在保存时自动更新
return await this.userRepository.save(user)
}
async deleteUser(id: string): Promise<void> {
// 软删除,设置 isDelete = '1'
await this.userRepository.update(id, {
isDelete: BoolNum.Yes,
updateUser: 'admin'
})
}
}高级用法
自定义时间格式化
typescript
@BaseColumn({
type: 'datetime',
transformer: {
from: (date) => date && dayjs(date).format('YYYY年MM月DD日 HH:mm:ss'),
to: (value: string) => value,
},
name: 'custom_time',
comment: '自定义时间字段'
})
customTime: string复合唯一约束
typescript
@BaseColumn({ length: 50 })
@DbUnique
tenantId: string
@BaseColumn({ length: 50 })
@DbUnique
userId: string
// 在数据库层面可以通过联合索引实现复合唯一约束条件字段验证
typescript
export class SysUser extends BaseEntity {
@BaseColumn({ length: 50 })
@DbUnique
username: string
@BaseColumn({ length: 100 })
email: string
// 自定义验证逻辑
async validate(): Promise<void> {
if (this.email && !this.email.includes('@')) {
throw new Error('邮箱格式不正确')
}
}
}最佳实践
1. 字段命名规范
typescript
// ✅ 推荐:使用清晰的字段名
@BaseColumn({ length: 50, comment: '真实姓名' })
realName: string
// ❌ 不推荐:含义模糊的字段名
@BaseColumn({ length: 50 })
name: string2. 合理使用唯一约束
typescript
// 对于业务上必须唯一的字段添加 @DbUnique
@BaseColumn({ length: 50 })
@DbUnique
username: string
// 对于可以重复的字段不要添加唯一约束
@BaseColumn({ length: 100 })
nickname: string3. 字符串长度控制
typescript
// 对于可能输入较长文本的字段启用自动截断
@BaseColumn({
length: 200,
comment: '个人简介',
overLengthCut: true
})
bio: string4. 时间字段处理
typescript
// 创建时间由系统自动设置,不需要手动赋值
// 更新时间会在每次更新时自动刷新
const user = new SysUser()
user.username = 'testuser'
user.createUser = 'admin' // 只需要设置创建人
// createTime 和 updateTime 会自动处理常见问题
Q: 如何禁用某些基础字段?
A: 可以通过继承后重新定义字段来覆盖:
typescript
@MyEntity('simple_entity')
export class SimpleEntity extends BaseEntity {
// 重新定义字段,移除不需要的约束
@Column({ type: 'varchar', length: 50 })
createUser: string
// 或者完全移除某个字段(不推荐)
// @Exclude()
// createTime: string
}Q: 如何自定义软删除逻辑?
A: 可以重写相关方法或使用不同的删除标识:
typescript
export class CustomEntity extends BaseEntity {
@DeleteDateColumn({
type: 'datetime',
name: 'deleted_at',
comment: '删除时间'
})
deletedAt: Date
}Q: 如何处理大量文本字段?
A: 使用 text 类型并考虑性能优化:
typescript
@BaseColumn({
type: 'text',
comment: '详细描述'
})
description: string
// 对于搜索频繁的长文本,考虑添加全文索引Q: 如何实现字段级别的权限控制?
A: 可以在实体中添加权限检查逻辑:
typescript
export class SecureEntity extends BaseEntity {
@BaseColumn({ length: 100 })
sensitiveData: string
// 自定义方法进行权限检查
canViewField(fieldName: string, userId: string): boolean {
// 实现具体的权限逻辑
return true
}
}