logo
火山博客
导航

typeORM - Join操作

2024-11-11
17阅读时间5分钟

TypeORM中的Join类型

在TypeORM中,我们主要使用以下几种方式来执行Join操作:

  1. innerJoin(内连接)
  2. leftJoin(左连接)
  3. leftJoinAndSelect(左连接并选择)
  4. innerJoinAndSelect(内连接并选择)
  5. rightJoin(右连接)
  6. rightJoinAndSelect(右连接并选择)

其他关系处理方法

除了上述Join操作外,TypeORM还提供了一些其他用于处理实体关系的方法:

  • relation: 用于指定要加载的关系
  • loadRelationCountAndMap: 加载关联实体的数量并映射到主实体的属性
  • loadRelationIdAndMap: 加载关联实体的ID并映射到主实体的属性

基本用法

Typescript
// 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;
}

数据库模拟数据

Txt
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 }

一,innerJoin (内连接)

Typescript
const result = await connection
    .getRepository(User)
    .createQueryBuilder("user")
    .innerJoin("user.posts", "post")
    .getMany();


console.log(result);
// 输出结果:
[
  { id: 1, name: "火山" },
  { id: 2, name: "小明" }
]

innerJoin只返回两个表中都有匹配的记录。在这个例子中,只有火山和小明有关联的文章,所以只返回了他们的记录。

二,leftJoin (左连接)

Typescript
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)没有匹配的记录。这就是为什么小红也被包含在结果中,尽管他没有发表任何文章。

三,leftJoinAndSelect (左连接并选择)

Typescript
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)。

四,innerJoinAndSelect (内连接并选择)

Typescript
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只返回两个表中都有匹配的记录,并加载关联的实体。小红没有文章,所以不包含在结果中。

五,rightJoin (右连接)

Typescript
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。

六,rightJoinAndSelect (右连接并选择)

Typescript
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。

AI播客
文章概要
AI播客
2024 © Powered by
hsBlog
|
后台管理