在TypeORM中,我们主要使用以下几种方式来执行Join操作:
除了上述Join操作外,TypeORM还提供了一些其他用于处理实体关系的方法:
// user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Post } from "./Post";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Post, post => post.author)
posts: Post[];
}
// post.entity.ts
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
import { User } from "./User";
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(() => User, user => user.posts)
author: User;
}
数据库模拟数据
Users:
{ id: 1, name: "火山" }
{ id: 2, name: "小明" }
{ id: 3, name: "小红" }
Posts:
{ id: 1, title: "TypeORM基础", author: 1 }
{ id: 2, title: "Node.js入门", author: 1 }
{ id: 3, title: "React教程", author: 2 }
{ id: 4, title: "SQL高级技巧", author: null }
const result = await connection
.getRepository(User)
.createQueryBuilder("user")
.innerJoin("user.posts", "post")
.getMany();
console.log(result);
// 输出结果:
[
{ id: 1, name: "火山" },
{ id: 2, name: "小明" }
]
innerJoin只返回两个表中都有匹配的记录。在这个例子中,只有火山和小明有关联的文章,所以只返回了他们的记录。
const result = await connection
.getRepository(User)
.createQueryBuilder("user")
.leftJoin("user.posts", "post")
.getMany();
console.log(result);
//输出结果
[
{ id: 1, name: "火山" },
{ id: 2, name: "小明" },
{ id: 3, name: "小红" }
]
leftJoin返回左表(User)的所有记录,即使右表(Post)没有匹配的记录。这就是为什么小红也被包含在结果中,尽管他没有发表任何文章。
const result = await connection
.getRepository(User)
.createQueryBuilder("user")
.leftJoinAndSelect("user.posts", "post")
.getMany();
console.log(result);
//输出结果:
[{
id: 1,
name: "火山",
posts: [{
id: 1,
title: "TypeORM基础"
},
{
id: 2,
title: "Node.js入门"
}]
},
{
id: 2,
name: "小明",
posts: [{
id: 3,
title: "React教程"
}]
},
{
id: 3,
name: "小红",
posts: []
}]
leftJoinAndSelect不仅执行左连接,还会选择并加载关联的实体(在这里是posts)。
const result = await connection
.getRepository(User)
.createQueryBuilder("user")
.innerJoinAndSelect("user.posts", "post")
.getMany();
console.log(result);
//输出结果:
[{
id: 1,
name: "火山",
posts: [{
id: 1,
title: "TypeORM基础"
},
{
id: 2,
title: "Node.js入门"
}]
},
{
id: 2,
name: "小明",
posts: [{
id: 3,
title: "React教程"
}]
}]
innerJoinAndSelect只返回两个表中都有匹配的记录,并加载关联的实体。小红没有文章,所以不包含在结果中。
const result = await connection
.getRepository(Post)
.createQueryBuilder("post")
.rightJoin("post.author", "user")
.getMany();
console.log(result);
//输出结果:
[
{ id: 1, title: "TypeORM基础" },
{ id: 2, title: "Node.js入门" },
{ id: 3, title: "React教程" },
{ id: 4, title: "SQL高级技巧" }
]
rightJoin返回右表(User)的所有记录,即使左表(Post)没有匹配的记录。注意,这里我们从Post实体开始查询,以便演示rightJoin。
const result = await connection
.getRepository(Post)
.createQueryBuilder("post")
.rightJoinAndSelect("post.author", "user")
.getMany();
console.log(result);
//输出结果:
[
{ id: 1, title: "TypeORM基础", author: { id: 1, name: "火山" } },
{ id: 2, title: "Node.js入门", author: { id: 1, name: "火山" } },
{ id: 3, title: "React教程", author: { id: 2, name: "小明" } },
{ id: 4, title: "SQL高级技巧", author: null },
{ author: { id: 3, name: "小红" } }
]
rightJoinAndSelect不仅执行右连接,还会选择并加载关联的实体(在这里是author)。注意,小红被包含在结果中,尽管他没有发表任何文章。同时,"SQL高级技巧"这篇文章的作者为null。