TypeORM 常用方法及 NestJS 实现示例
- 查询操作
方法 说明 示例代码
find() 查询符合条件的所有记录
// 查询所有角色const roles = await this.roleRepository.find();| findOne() | 根据条件查询单条记录 |
// 根据ID查询角色
const role = await this.roleRepository.findOne({ where: { id: 1 } });
| `findAndCount()` | 返回查询结果及总数(适合分页) |
const [roles, total] = await this.roleRepository.findAndCount({
where: { name: Like('%admin%') },
});
| `createQueryBuilder()` | 构建复杂查询(支持JOIN、排序等) |
const roles = await this.roleRepository
.createQueryBuilder('role')
.innerJoinAndSelect('role.menus', 'menu')
.where('role.name = :name', { name: 'admin' })
.getMany();
---
#### **2. 增删改操作**
| 方法 | 说明 | 示例代码 |
|------|------|----------|
| `save()` | 保存新记录或更新已有记录 |
// 创建新角色
const newRole = this.roleRepository.create(createRoleDto);
await this.roleRepository.save(newRole);
| update() | 更新符合条件的记录 |
typescript
await this.roleRepository.update({ id: 1 }, { name: 'super-admin' });
| `delete()` | 删除记录 |
await this.roleRepository.delete({ id: 1 });
---
#### **3. 关联操作**
| 场景 | 说明 | 示例代码 |
|------|------|----------|
| **预加载关联数据** | 查询时自动加载关联表(如角色关联的菜单) |
const role = await this.roleRepository.findOne({
where: { id: 1 },
relations: { menus: true }, // 加载关联的menus
});
| **保存关联数据** | 通过关系字段直接关联 |
const role = new Role();
role.name = 'admin';
role.menus = [menu1, menu2]; // 菜单实体集合
await this.roleRepository.save(role);
---
#### **4. 高级功能**
| 方法 | 说明 | 示例代码 |
|------|------|----------|
| `transaction()` | 事务处理(确保操作原子性) |
await this.dataSource.transaction(async (manager) => {
await manager.save(role);
await manager.save(menu);
});
| `softDelete()` | 软删除(标记删除而非物理删除) |
await this.roleRepository.softDelete({ id: 1 });
| `getRepository()` | 获取子实体仓库(嵌套关系) |
const menuRepo = this.roleRepository.getRepository(MenuEntity);
---
#### **5. 条件构造器(Where 条件)**
| 操作符 | 说明 | 示例 |
|--------|------|------|
| `In` | 多值匹配 | `id: In([1, 2, 3])` |
| `Like`/`NotLike` | 模糊匹配 | `name: Like('%admin%')` |
| `Between` | 范围查询 | `age: Between(18, 60)` |
| `IsNull`/`IsNotNull` | 空值判断 | `deletedAt: IsNull()` |
---
### **完整示例(结合你的 `role.service.ts`)**
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { RoleEntity } from './entities/role.entity'; // 根据实际路径调整
import { CreateRoleDto } from './dto/create-role.dto';
@Injectable()
export class RoleService {
constructor(
@InjectRepository(RoleEntity)
private readonly roleRepository: Repository<RoleEntity>,
) {}
// 创建角色
async create(createRoleDto: CreateRoleDto) {
const newRole = this.roleRepository.create(createRoleDto);
return await this.roleRepository.save(newRole);
}
// 查询所有角色(带分页)
async findAll(page: number, limit: number) {
const [roles, total] = await this.roleRepository.findAndCount({
skip: (page - 1) * limit,
take: limit,
});
return { roles, total };
}
// 根据ID查询角色(包含关联菜单)
async findOne(id: number) {
return await this.roleRepository.findOne({
where: { id },
relations: { menus: true },
});
}
// 更新角色
async update(id: number, updateData: any) {
await this.roleRepository.update(id, updateData);
return await this.roleRepository.findOne({ where: { id } });
}
// 删除角色(软删除示例)
async remove(id: number) {
await this.roleRepository.softDelete(id);
return { message: '角色已软删除' };
}
}
注意事项
依赖注入:确保在 RoleService 中通过 @InjectRepository 正确注入实体仓库。
事务管理:复杂操作(如创建角色并关联菜单)建议用 transaction 包裹。
错误处理:添加 try-catch 捕获数据库异常,例如:
typescript
try {
await this.roleRepository.save(role);
} catch (error) {
throw new HttpException('保存失败', 500);