TypeORM - Relações
Relações são usadas para referir-se ao relacionamento entre a tabela no banco de dados. Em geral, existe um relacionamento entre duas tabelas quando uma delas possui uma chave estrangeira que faz referência à chave primária da outra tabela. Esse recurso torna o banco de dados relacional mais poderoso e armazena informações de forma eficiente.
TypeORM permite que as entidades sejam relacionadas umas às outras e, subsequentemente, às tabelas do banco de dados. Em geral, o relacionamento pode ser classificado em quatro categorias mais amplas. Eles são os seguintes,
one-to-one- Um objeto de uma determinada entidade está relacionado a apenas um objeto da entidade de destino e vice-versa. Por exemplo, um país terá apenas uma capital e, da mesma forma, uma cidade será a capital de apenas um país.
many-to-one- Vários objetos de uma determinada entidade se relacionam a um objeto da entidade de destino. Por exemplo, a cidade pertence a apenas um país, mas o país pode ter várias cidades.
one-to-many - O mesmo que muitos para um, exceto que a relação é invertida.
many-to-many- Vários objetos de uma determinada entidade estão relacionados a vários objetos da entidade de destino. Por exemplo, um artigo pode ser marcado em vários tópicos, como linguagem de programação, finanças, etc. e, ao mesmo tempo, uma determinada tag pode ter vários artigos também.
TypeORM também oferece opções para aprimorar o relacionamento das entidades. Eles são os seguintes -
- eager - O objeto de entidade de origem também carrega os objetos de entidade de destino.
- cascade - O objeto da entidade de destino é inserido ou atualizado enquanto o objeto da entidade de origem é inserido ou atualizado.
- onDelete - Objetos de entidade de destino também são excluídos enquanto o objeto de entidade de origem é excluído.
- primary - Usado para especificar se a coluna de relação é a chave primária ou não.
- nullable - Usado para especificar se a coluna de relação é anulável ou não.
Vamos examinar os diferentes tipos de mapeamento de relação em detalhes.
Um a um
Como aprendemos anteriormente, ele é referido pela instância de um campo da tabela contém a instância de outro campo da tabela e vice-versa. Vamos criar umDetails mesa -
Details.ts
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity()
export class Details {
@PrimaryGeneratedColumn()
id: number;
@Column()
gender: string;
@Column()
country: string;
}
Vamos criar uma outra entidade Cliente da seguinte maneira -
Customer.ts
import {Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn} from "typeorm";
import {Details} from "./Details";
@Entity()
export class Customer {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToOne(type => Details) @JoinColumn()
details: Details;
}
Aqui,
Nós adicionamos mapeamento OneToOne para Details mesa. @JoinColumn() contém um "id de relação" e uma chave estrangeira para Customermesa. Podemos salvar a relação emindex.ts como segue -
const details = new Details(); details.gender = "female"; details.country = "india" await connection.manager.save(details);
const customer = new Customer(); customer.name = 'customer1'; customer.details = Details; await connection.manager.save(Customer);
Um para Muitos e Muitos para Um
Como aprendemos anteriormente, ele é referido pela instância do primeiro campo da tabela que contém as várias instâncias do segundo campo da tabela chamado One-to-Many mapeamento e várias instâncias da primeira tabela contém apenas uma instância da segunda tabela chamada Many-to-One mapeamento.
Considere um exemplo de Student e project entidades enquanto o aluno pode trabalhar em mais de um projeto, mas cada projeto é tratado por apenas um aluno.
Vamos criar um Project entidade como segue -
Projeto
import {Entity, PrimaryGeneratedColumn, Column, ManyToOne} from "typeorm"; import {Student} from "./Student";
@Entity()
export class Project {
@PrimaryGeneratedColumn()
id: number;
@Column()
projects: string;
@ManyToOne(type => Student, student => student.projects) student: Student;
}
Agora, nós criamos Student entidade como abaixo -
import {Entity, PrimaryGeneratedColumn, Column, OneToMany} from "typeorm"; import {Project} from "./Project";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(type => Project, project => project.student) projects: Project[];
}
Aqui,
@OneToMany propriedade mapeada Project e @ManyToOne propriedade mapeada para Student. Contudo,@OneToMany não pode existir sem @ManyToOne e @ManyToOne propriedade contém “id de relação” e chave estrangeira.
Podemos salvar a conexão em index.ts como segue -
const proj1 = new Project(); proj1.projects = "database management"; await connection.manager.save(proj1);
const proj2 = new Project(); proj2.projects = "web application"; await connection.manager.save(proj2);
const stud = new Student(); stud.name = "Student1"; stud.projects = [proj1, proj2]; await connection.manager.save(stud);
Muitos para muitos
Como aprendemos anteriormente, ele é referido por vários registros em uma tabela que estão relacionados a vários registros em outra tabela. Considere um exemplo, o aluno universitário pode estar matriculado em várias turmas ao mesmo tempo, o que significa que o aluno pode ter quatro ou cinco turmas por semestre e uma turma pode ter muitos alunos.
Podemos simplesmente concluir, um aluno tem muitas turmas e uma turma tem muitos alunos. Vamos criar uma entidade paraClasses como segue -
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity()
export class Classes {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}
Agora, nós criamos Student entidade como abaixo -
import {Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable} from "typeorm";
import {Classes} from "./Classes";
@Entity()
export class Student {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
subjects: string;
@ManyToMany(type => Classes) @JoinTable()
classes: Classes[];
}