TypeORM:如何查询带关联与条件的MyObject树形实体
解决方案:结合TreeRepository的QueryBuilder与buildTree方法
要实现同时满足指定user.id条件、加载关联数据、返回完整树形结构的查询,你可以通过TypeORM的TreeRepository.createQueryBuilder自定义查询,再用buildTree方法将扁平结果组装为树形结构,具体步骤如下:
1. 确认实体配置正确性
先确保MyObject实体已正确配置树形结构与关联关系:
import { Entity, PrimaryGeneratedColumn, ManyToOne, OneToMany, ManyToMany, JoinTable, Tree, TreeParent, TreeChildren } from "typeorm"; import { User } from "./User"; import { Comment } from "./Comment"; import { Tag } from "./Tag"; @Entity() @Tree("closure-table") export class MyObject { @PrimaryGeneratedColumn() id: number; // 多对一关联User @ManyToOne(() => User) user: User; // 一对多关联Comment @OneToMany(() => Comment, comment => comment.myObject) comments: Comment[]; // 多对多关联Tag @ManyToMany(() => Tag) @JoinTable() tags: Tag[]; // 树形结构父节点 @TreeParent() parent: MyObject; // 树形结构子节点 @TreeChildren() children: MyObject[]; }
2. 构建带条件与关联的查询
使用TreeRepository的createQueryBuilder,添加用户ID过滤条件,并通过leftJoinAndSelect加载关联数据,获取所有符合条件的扁平节点:
import { getManager } from "typeorm"; import { MyObject } from "./entities/MyObject"; const targetUserId = 1; // 替换为目标用户ID // 获取TreeRepository实例 const treeRepo = getManager().getTreeRepository(MyObject); // 构建自定义查询:过滤用户ID + 加载关联数据 const flatNodes = await treeRepo .createQueryBuilder("myObject") // 加载关联的User数据 .leftJoinAndSelect("myObject.user", "user") // 加载关联的Comment列表 .leftJoinAndSelect("myObject.comments", "comments") // 加载关联的Tag列表 .leftJoinAndSelect("myObject.tags", "tags") // 过滤指定用户ID的实体 .where("user.id = :userId", { userId: targetUserId }) .getMany();
3. 转换扁平数据为树形结构
利用TreeRepository.buildTree方法,将查询得到的扁平节点数组自动组装为嵌套的完整树形结构:
const treeNodes = treeRepo.buildTree(flatNodes);
关键说明
createQueryBuilder弥补了findTrees()无法自定义查询条件和加载关联的缺陷,支持灵活扩展查询逻辑。buildTree依赖实体上的@TreeParent、@TreeChildren装饰器与闭包表数据,自动完成扁平数据到树形结构的转换。- 若仅需加载用户的根节点及其子树,可在查询中额外添加根节点过滤条件:
.andWhere("myObject.parent IS NULL")
内容的提问来源于stack exchange,提问作者sirzento
相关产品推荐
相关产品推荐

