自学内容网 自学内容网

OneToMany 和 ManyToOne

在使用 ORM(如 TypeORM)进行实体关系设计时,@OneToMany@ManyToOne 是非常重要的注解,常用来表示两个实体之间的一对多关系。下面通过例子详细说明它们的使用场景和工作方式。


@OneToMany@ManyToOne 的基本概念

  1. @ManyToOne
    表示 “多” 的一方指向 “一” 的一方。它总是定义在关系的 “多” 一侧。

    • 数据库中通常对应一个外键列。
    • 该装饰器是关系的拥有方,负责维护外键。
  2. @OneToMany
    表示 “一” 的一方指向 “多” 的一方。它总是定义在关系的 “一” 一侧。

    • 数据库中没有直接对应的列,而是反向映射。
    • 必须与 @ManyToOne 配合使用,不能单独存在。

示例:用户与文章的关系

场景:

  • 一个用户可以拥有多篇文章。
  • 每篇文章属于一个用户。
1. 实体设计
User 实体
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
import { Article } from './article.entity';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  // 一个用户拥有多篇文章
  @OneToMany(() => Article, (article) => article.author)
  articles: Article[];
}
Article 实体
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
import { User } from './user.entity';

@Entity()
export class Article {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @ManyToOne(() => User, (user) => user.articles, { onDelete: 'CASCADE' })
  author: User; // 每篇文章属于一个用户
}

2. 数据库结构

根据上述实体,TypeORM 将生成以下表结构:

User

idname
1Alice
2Bob

Article

idtitleauthorId
1First Post1
2Second Post1
3Third Post2

3. 插入数据
创建用户和文章
const userRepository = dataSource.getRepository(User);
const articleRepository = dataSource.getRepository(Article);

// 创建用户
const user = userRepository.create({ name: 'Alice' });
await userRepository.save(user);

// 创建文章
const article1 = articleRepository.create({ title: 'First Post', author: user });
const article2 = articleRepository.create({ title: 'Second Post', author: user });
await articleRepository.save([article1, article2]);

4. 查询数据
查询用户的文章
const userWithArticles = await userRepository.findOne({
  where: { id: 1 },
  relations: ['articles'],
});

console.log(userWithArticles);

输出:

{
  "id": 1,
  "name": "Alice",
  "articles": [
    { "id": 1, "title": "First Post" },
    { "id": 2, "title": "Second Post" }
  ]
}
查询文章及其作者
const articleWithAuthor = await articleRepository.findOne({
  where: { id: 1 },
  relations: ['author'],
});

console.log(articleWithAuthor);

输出:

{
  "id": 1,
  "title": "First Post",
  "author": { "id": 1, "name": "Alice" }
}

关键点总结

  1. @ManyToOne 是外键的维护者

    • 它在数据库中定义外键列(如 authorId)。
    • 用于指向关系的 “一” 侧。
  2. @OneToMany 是关系的反向映射

    • 它没有单独的数据库列。
    • 它仅用作 @ManyToOne 的反向映射,表示 “一” 侧可以访问所有 “多” 侧的记录。
  3. relations 必须手动加载

    • TypeORM 默认不会加载关联字段,需在查询时指定 relations
  4. cascade 选项

    • cascade: true 允许保存或删除时级联操作(如在保存用户时自动保存其文章)。


原文地址:https://blog.csdn.net/jefferylong/article/details/143840867

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!