当前位置: 首页 > article >正文

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 允许保存或删除时级联操作(如在保存用户时自动保存其文章)。


http://www.kler.cn/a/403747.html

相关文章:

  • el-progress进度条框开着时,要实时刷新显示进度条
  • 99.【C语言】数据结构之二叉树的基本知识
  • 【国产MCU系列】-GD32F470-内部集成电路总线接口(I2C)
  • 【Nginx从入门到精通】05-安装部署-虚拟机不能上网简单排错
  • 离散数学---概率, 期望
  • Spring Cloud Stream实现数据流处理
  • 使用数据库批量插入与循环单个插入:优势与区别
  • MyBatis的resultType和resultMap区别
  • 力扣 LeetCode 112. 路径总和(Day8:二叉树)
  • 失落的Apache JDBM(Java Database Management)
  • 【项目实战】基于 LLaMA-Factory 通过 LoRA 微调 Qwen2
  • 2024信创数据库TOP30之蚂蚁集团OceanBase
  • 最新智能AI问答运营系统(SparkAi)一站式AIGC系统,GPT-4.0/GPT-4o多模态模型+联网搜索提问+AI绘画+管理后台,用户会员套餐
  • Excel中批量替换字符大PK:Excel VS. Python
  • c ++零基础可视化——vector
  • WebSocket详解、WebSocket入门案例
  • React渲染流程与更新diff算法
  • AMD(Xilinx) FPGA配置Flash大小选择
  • Linux:权限相关知识详解
  • 基于yolov8、yolov5的茶叶等级检测识别系统(含UI界面、训练好的模型、Python代码、数据集)
  • hhdb数据库介绍(9-26)
  • 当mysql的slave无法同步master数据时,如何基本不断业务重置主从同步关系
  • MySQL社区版的启动与连接
  • 数据集-目标检测系列- 花卉 鸡蛋花 检测数据集 frangipani >> DataBall
  • TensorFlow 2.0 windows11 GPU 训练环境配置
  • Unity3D空中突袭(1)场景导入