建设网站域名备案查询网站推广维护
在使用 ORM(如 TypeORM)进行实体关系设计时,@OneToMany 和 @ManyToOne 是非常重要的注解,常用来表示两个实体之间的一对多关系。下面通过例子详细说明它们的使用场景和工作方式。
@OneToMany 和 @ManyToOne 的基本概念
 
-  
@ManyToOne
表示 “多” 的一方指向 “一” 的一方。它总是定义在关系的 “多” 一侧。- 数据库中通常对应一个外键列。
 - 该装饰器是关系的拥有方,负责维护外键。
 
 -  
@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 表
| id | name | 
|---|---|
| 1 | Alice | 
| 2 | Bob | 
Article 表
| id | title | authorId | 
|---|---|---|
| 1 | First Post | 1 | 
| 2 | Second Post | 1 | 
| 3 | Third Post | 2 | 
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" }
}
 
关键点总结
-  
@ManyToOne是外键的维护者:- 它在数据库中定义外键列(如 
authorId)。 - 用于指向关系的 “一” 侧。
 
 - 它在数据库中定义外键列(如 
 -  
@OneToMany是关系的反向映射:- 它没有单独的数据库列。
 - 它仅用作 
@ManyToOne的反向映射,表示 “一” 侧可以访问所有 “多” 侧的记录。 
 -  
relations必须手动加载:- TypeORM 默认不会加载关联字段,需在查询时指定 
relations。 
 - TypeORM 默认不会加载关联字段,需在查询时指定 
 -  
cascade选项:cascade: true允许保存或删除时级联操作(如在保存用户时自动保存其文章)。
 
