【typeorm】typeorm学习笔记(二)

14 篇文章 3 订阅
8 篇文章 0 订阅

前言

  • 本篇是一些x对x的写法。

一对一

  • 一般情况一对一要创建双向关系,以上次创建的user表为例,额外新增user的扩展表user_extend:
import {
	Entity,
	PrimaryGeneratedColumn,
	Column,
	OneToOne,
	JoinColumn,
} from "typeorm";
import { User } from "./User";

@Entity({ name: "user_extend" })
export class UserExtend {
	@PrimaryGeneratedColumn({
		type: "int",
		name: "id",
		comment: "主键id",
	})
	id: number;

	@Column({
		type: "varchar",
		length: 11,
		nullable: true,
		name: "mobile",
		comment: "手机号码",
	})
	mobile: string;

	@Column({
		type: "varchar",
		length: 50,
		nullable: true,
		name: "address",
		comment: "地址",
	})
	address: string;

	// 使用@OneToOne装饰允许我们在两个实体之间创建一对一的关系
	@OneToOne((type) => User, (user) => user.userDetail)
	// @JoinColumn装饰器,表明实体键的对应关系
	@JoinColumn()
	user: User;
}
  • 关键在最下面3行,一个是调用了OneToOne与User表的userDetail进行关联,使用JoinColumn与User表进行关联。如果是单项关系,OneToOne第二个参数可以不传。
  • 同时,User表新建字段userDetail:
	@OneToOne((type) => UserExtend, (userExtend) => userExtend.user)
	@JoinColumn()
	userDetail: UserExtend;
  • 插入数据有点不一样就是做个关联,然后有个保存顺序。
createConnection().then(async connection => {
  // 创建一个用户
  const user = new User();
  user.username = '王五';
  user.password = '123456';

  const userExtend = new UserExtend();
  userExtend.mobile = '13412345678';
  userExtend.address = '中国';
  // 关联两个数据模型
  userExtend.user = user;

  // 必须先保存用户表,因为他要提供主键出来
  const userRepository = connection.getRepository(User);
  await userRepository.save(user);

  const userExtendRepository = connection.getRepository(UserExtend);
  await userExtendRepository.save(userExtend);
  console.log('插入数据成功');
}).catch(error => console.log(error));
  • 查询:这个result是user表有userDetail字段的。
	// 使用relations关联查询数据(正向查找)
		const userRepository = connection.getRepository(User);
		// userDetail就是当前表中定义的字段
		const result = await userRepository.find({ relations: ["userDetail"] });
  • 反向查询:取得是user扩展表,其字段user关联user表。
	const userExtendRepository = connection.getRepository(UserExtend);
		const result = await userExtendRepository.find({ relations: ["user"] });
		console.log(result);

一对多

  • 制作帖子对用户的关系:
import {
	Entity,
	PrimaryGeneratedColumn,
	Column,
	CreateDateColumn,
	UpdateDateColumn,
} from "typeorm";

@Entity({ name: "posts" })
export class Posts {
	@PrimaryGeneratedColumn({
		type: "int",
		name: "id",
		comment: "主键id",
	})
	id: number;

	@Column({
		type: "varchar",
		nullable: false,
		length: 50,
		unique: true,
		name: "title",
		comment: "标题",
	})
	title: string;

	@Column({
		type: "text",
		nullable: true,
		name: "content",
		comment: "内容",
	})
	content: string;

	@Column("tinyint", {
		nullable: false,
		default: () => 0,
		name: "is_del",
		comment: "是否删除,1表示删除,0表示正常",
	})
	isDel: number;

	@CreateDateColumn({
		type: "timestamp",
		nullable: false,
		name: "created_at",
		comment: "创建时间",
	})
	createdAt: Date;

	@UpdateDateColumn({
		type: "timestamp",
		nullable: false,
		name: "updated_at",
		comment: "更新时间",
	})
	updateAt: Date;
}
  • 同样的,两边都加上ManyToOne和OneToMany :
	@ManyToOne((type) => User, (user) => user.posts)
	user: User;
	@OneToMany((type) => Posts, (post) => post.user)
	posts: Posts[];
  • oneToOne需要加column ,而OneToMany会自动加列,可以不用加。
  • 查询:
		const userRepository = connection.getRepository(User);
		// relations存放一个数组,可以存放多个关联关系的
		const result = await userRepository.find({ relations: ["posts"] });
		console.log(result);
const postsRepository = connection.getRepository(Posts);
		const result = await postsRepository.find({ relations: ["user"] });
		console.log(result);

多对多

  • 一般都是构建一张中间表来存放两个表的主键,当要更新一个数据的时候会先去中间表中根据条件删除之前的数据,然后重新添加进去。
  • 这里以一个帖子可能有多个tag ,多个tag可能对应一个帖子为例:
import {
	Entity,
	PrimaryGeneratedColumn,
	Column,
	ManyToMany,
	JoinTable,
} from "typeorm";
import { Posts } from "./Posts";

@Entity("tags")
export class Tags {
	@PrimaryGeneratedColumn({
		type: "int",
		name: "id",
		comment: "主键id",
	})
	id: number;

	@Column({
		type: "varchar",
		name: "name",
		nullable: false,
		unique: true,
		comment: "tag名称",
	})
	name: string;

	@ManyToMany((type) => Posts, (post) => post.tags)
	@JoinTable({ name: "tags_posts" }) // 可以手动指定中间表明
	posts: Posts[];
}
	@ManyToMany((type) => Tags, (tag) => tag.posts)
	tags: Tags[];
  • 运行后发现多了个中间表tags_posts以及tags表。
  • 创建表:
// 创建tag1
		const tag1 = new Tags();
		tag1.name = "mysql";

		// 创建tag2
		const tag2 = new Tags();
		tag2.name = "node";

		// 帖子一
		const posts1 = new Posts();
		posts1.title = "文章一";
		posts1.content = "文章一内容";
		posts1.tags = [tag1, tag2];

		// 帖子二
		const posts2 = new Posts();
		posts2.title = "文章二";
		posts2.content = "文章二内容";
		posts2.tags = [tag1];

		// 创建一个用户
		const user = new User();
		user.username = "王五";
		user.password = "123456";
		user.posts = [posts1, posts2];

		const userRepository = connection.getRepository(User);
		const postsRepository = connection.getRepository(Posts);
		const tagRepository = connection.getRepository(Tags);
		await tagRepository.save(tag1);
		await tagRepository.save(tag2);

		await postsRepository.save(posts1);
		await postsRepository.save(posts2);
		await userRepository.save(user);
		console.log("添加数据成功");
  • 查询:
const postsRepository = connection.getRepository(Posts);
const result = await postsRepository.findOne({ where: { id: 1 }, relations: ['tags', 'user'] });
console.log(result);
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值