现有两张表 store
和 teacher
,关系为 1:N ,store
表的数据表为
teacher
的数据表为
我现在想查询 storeId = 1 对应的 teacherName ,我的 createQueryBuilder 代码如下
const sqlResult = await this.storeRepository
.createQueryBuilder('store')
.innerJoinAndSelect(Teacher, 'teacher', 'store.id = teacher.storeId')
.select([ 'teacher.name'])
.where('store.id = :id', {id})
.getOne()
查询的结果是 null ,我起初以为是我的 createQueryBuilder 代码有问题,所以直接运行 createQueryBuilder 生成的 SQL 代码,发现又能正常获取数据,想问下大家是什么原因呢?
1
hua123s 2023-05-22 21:29:55 +08:00 via iPhone
id 字符串?换成 number 试试呢
|
2
feeeff OP append:
store 的表结构定义为 ``` @Entity() export class Store extends BaseEntity{ @Column() name: string @Column() description: string @OneToMany(()=>Teacher, (teacher)=>teacher.store) teachers: Teacher[] } ``` teacher 的表结构定义为 ``` @Entity() export class Teacher extends BaseEntity{ @Column() name: string @ManyToOne(() => Store, (store) => store.teachers) @JoinColumn({ name: "storeId" }) store: Store; } ``` |
3
feeeff OP @hua123s 感谢你的回答,我刚刚试了你的方法,还是不行,结果如下图
![image]( https://github.com/wojiaofengzhongzhuifeng/study/assets/25478678/3ad51978-7208-4991-8d34-9e0d97fdc01a) |
4
hua123s 2023-05-22 21:41:29 +08:00 via iPhone
这段代码似乎是使用 TypeORM 进行数据库查询和连接操作。然而,有一个问题在于选择的字段 `'teacher.name'` 并未包含在内连接语句的 ON 条件中。在内连接时,ON 条件用于指定连接两个表的关联条件,以确保只返回符合条件的结果。
在你提供的代码中,使用了内连接 `innerJoinAndSelect()` 来连接 `store` 表和 `teacher` 表,并指定了 `store.id = teacher.storeId` 作为关联条件。然而,在选择字段时,只选择了 `'teacher.name'`,而没有选择 `store` 表中的任何字段。 修复这个问题的方法是在选择字段时,也包括需要的 `store` 表字段,例如 `'store.id'` 或其他相关的字段。修改后的代码如下: ```typescript const sqlResult = await this.storeRepository .createQueryBuilder('store') .innerJoinAndSelect(Teacher, 'teacher', 'store.id = teacher.storeId') .select(['store.id', 'teacher.name']) .where('store.id = :id', { id }) .getOne(); ``` 现在,选择字段中包括了 `store` 表的 `'store.id'` 和 `teacher` 表的 `'teacher.name'`,这样就可以正确地返回结果了。请根据你的需求修改选择的字段,并确保关联条件符合你的数据模型。 太晚了,早点睡吧。 |
5
lovedebug 2023-05-22 21:46:44 +08:00
1. 需要同时使用 ManyToOne 和 OneToMany 的注解
2. 用 getMany()替代 getOne() |
6
feeeff OP @hua123s
按照提示的结果如下 ![image]( https://github.com/wojiaofengzhongzhuifeng/study/assets/25478678/79f09389-2dc2-4de2-a305-ee8617e7e3a2) 只返回的 store ( 1 表)的字段,teacher ( N 表)的字段不返回 |
7
feeeff OP @lovedebug
1. 我在 entity 同时添加了 OneToMany 和 ManyToOne ,在二楼哈 2. 结果如下: ![image]( https://github.com/wojiaofengzhongzhuifeng/study/assets/25478678/01958564-4ee4-416a-b244-2946ec2bfaf8) |
9
hua123s 2023-05-22 22:38:01 +08:00 via iPhone
@feeeff 看起来你的问题应该用 getRaw ,当然一般而言不会像你这样写。所以你这样,我很陌生。
|
11
hua123s 2023-05-23 19:24:16 +08:00
其实我的回答是错误的。我问了 GPT4 ,
在这段查询代码中,你没有包含你要查询的 store 实体。虽然你在创建查询时加入了 store ,但在 select 语句中,你并没有显式地包含 store 。如果你希望获取特定的 store 和与其关联的 teacher 的 name ,你需要在 select 语句中指明。 另外,根据 TypeORM 的 API 文档,当你使用 innerJoinAndSelect 函数时,它会自动将你 join 的实体添加到 select 语句中。然而,你在 select 语句中显式地只选择了 'teacher.name',这可能导致 store 实体以及其他教师的信息被排除。 如果你希望获取 store 以及关联的 teacher 的 name ,你可以尝试以下的代码: javascript Copy code const sqlResult = await this.storeRepository .createQueryBuilder('store') .innerJoinAndSelect('store.teachers', 'teacher') .select(['store', 'teacher.name']) .where('store.id = :id', { id }) .getOne(); 这段代码将获取 store 以及其关联的所有教师的名字。注意,innerJoinAndSelect 的参数应当为关联字段的名字,而不是实体类的名字。另外,如果你只关心教师的名字,而不关心其他的字段,那么你可以在 select 语句中显式地选择 'teacher.name'。 如果你仍然遇到问题,那么可能是因为你的实体关系或者数据存在问题。你应该确保你的数据库中 store 和 teacher 之间的关联已经正确地建立,且你查询的 store 的 ID 确实存在,并且有关联的 teacher 。 希望这个答案对你有所帮助!如果你还有其他问题,欢迎你随时提问。 |