TypeORM - postgresSQL / 在数据库中保存数据

时间:2021-05-13 02:21:48

标签: postgresql typeorm

所以,我是 typeORM 的新手,实际上也是 postgresSQL DB 的新手,而且我对 typeORM 和在表之间建立关系有些不理解。

我的问题:所以,我有两个实体,User 和 Post。当您创建帖子时,我们使用@JoinColumn 将用户(帖子的创建者)存储在数据库中,当我转到用户表时,我可以看到该字段的名称(用户名),但是,在用户实体中,我们有一组帖子,但是,该字段没有出现在 postgres 数据库中,所以,当我创建一个关系时,@ManyToOne 和 @OneToMany,哪些数据存储在 DB 中,哪些没有?除此之外,当我获取东西时,我可以获取数组,但是,该数组是存储在数据库中还是什么?我对此有点困惑,所以,现在让我向您展示代码

用户实体

import {
  Entity as TOEntity,
  Column,
  Index,
  BeforeInsert,
  OneToMany
} from "typeorm";
import bcrypt from "bcrypt";
import { IsEmail, Length } from "class-validator";
import { Exclude } from "class-transformer";

import Entity from "./Entity";
import Post from "./Post";

@TOEntity("users")
export default class User extends Entity {
  constructor(user: Partial<User>) {
    super();
    Object.assign(this, user);
  }

  @Index()
  @IsEmail(undefined, { message: "Must be a valid email address" })
  @Length(5, 255, { message: "Email is empty" })
  @Column({ unique: true })
  email: string;

  @Index()
  @Length(3, 200, { message: "Must be at leat 3 characters long" })
  @Column({ unique: true })
  username: string;

  @Exclude()
  @Length(6, 200, { message: "Must be at leat 3 characters long" })
  @Column()
  password: string;

  @OneToMany(() => Post, post => post.user)
  posts: Post[];

  @BeforeInsert()
  async hashedPassword() {
    this.password = await bcrypt.hash(this.password, 6);
  }
}

发布实体

import {
  Entity as TOEntity,
  Column,
  Index,
  BeforeInsert,
  ManyToOne,
  JoinColumn,
  OneToMany
} from "typeorm";

import Entity from "./Entity";
import User from "./User";
import { makeid, slugify } from "../util/helpers";
import Sub from "./Sub";
import Comment from "./Comment";

@TOEntity("posts")
export default class Post extends Entity {
  constructor(post: Partial<Post>) {
    super();
    Object.assign(this, post);
  }

  @Index()
  @Column()
  identifier: string; // 7 Character Id

  @Column()
  title: string;

  @Index()
  @Column()
  slug: string;

  @Column({ nullable: true, type: "text" })
  body: string;

  @Column()
  subName: string;

  @ManyToOne(() => User, user => user.posts)
  @JoinColumn({ name: "username", referencedColumnName: "username" })
  user: User;

  @ManyToOne(() => Sub, sub => sub.posts)
  @JoinColumn({ name: "subName", referencedColumnName: "name" })
  sub: Sub;

  @OneToMany(() => Comment, comment => comment.post)
  comments: Comment[];

  @BeforeInsert()
  makeIdAndSlug() {
    this.identifier = makeid(7);
    this.slug = slugify(this.title);
  }
}

用户实体如何在数据库中看起来像一张表

enter image description here

所以,如您所见,没有带有名称帖子的字段(这很奇怪,因为正如我已经说过的,如果我可以获取它,如果我在数据库中看不到它,该数据在哪里)

>

现在,让我向您展示 Post 实体

enter image description here

我想了解什么:所以,我们有表格之间的关系,知道,我试图搜索一些东西以了解这一点,但我找不到任何东西,所以,如果你可以帮我解决这个烂摊子,我真的很感激,所以,谢谢你的时间!

1 个答案:

答案 0 :(得分:1)

让我们从这一节开始,逐个理解:

@ManyToOne(() => User, user => user.posts)
@JoinColumn({ name: "username", referencedColumnName: "username" })
user: User;

1. @ManyToOne(() => User, user => user.posts)

  • @ManyToOne:这个注解告诉 typeORM Post 实体将具有多对一的关系。从 postgres 数据库的角度来看,这意味着 posts 表将有一个新列(外键),它指向某个其他表中的记录。

  • () => User:这称为目标关系的定义。这有助于 typeORM 理解关系的目标是 User 实体。对于 postgres DB,这意味着 posts 表中的外键将引用 users 数据库中的一行

  • user => user.posts:这称为逆关系。这告诉 typeORM User 实体中关系的相关属性是 posts。从 postgres DB 的角度来看,这没有任何意义。只要有外键引用,就可以保持两张表的关系。

2. @JoinColumn({ name: "username", referencedColumnName: "username" })

  • @JoinColumn:在这个场景中,这个注解帮助typeORM理解posts表中外键列的名称和users表中被引用列的名称

  • name: "username":这是posts表中列的名称,它将唯一标识users表中的记录

  • referencedColumnName: "username":这是 users 表中列的名称,该列将被 username 表中的外键 posts 引用。< /p>


<块引用>

在 User 实体中,我们有一个 Posts 数组,但是,该字段没有出现在 postgres 数据库中

帖子数组用于 typeORM 返回链接帖子数组。 postgres DB 不需要包含关系。

<块引用>

当我创建关系时,@ManyToOne 和@OneToMany,哪些数据存储在数据库中,哪些不存储

您使用 @Column 修饰的任何属性都将在表中保持原样。对于关系,只会保存外键。例如,当您保存 Post 实体时,它只会保存该实体中的相关列 + username 外键。

<块引用>

当我获取东西时,我可以获取数组,但是,该数组是存储在数据库中还是什么?

当您查询 User 实体时,typeorm 使用注释将 users 表与 posts 表连接起来,并返回 posts 与您搜索的用户。但是在数据库中,将usersposts数据分别保存在各自的表中,并使用username外键来保持它们之间的关系。


我希望这能帮助您了解会发生什么。干杯? !!!