TypeORM - Guida rapida

Il framework TypeORM è un file Object Relational Mapping (ORM)struttura. In generale,Object la parte si riferisce al dominio / modello nella tua applicazione, Relational parte si riferisce alla relazione tra le tabelle nel Relational Database Management System (es. Oracle, MySQL, MS-SQL, PostgreSQL, ecc.) e infine Mapping parte si riferisce all'atto di collegare il modello e le nostre tabelle.

ORM è un tipo di strumento che mappa entità con tabelle di database. ORM fornisce un processo di sviluppo semplificato automatizzando la conversione da oggetto a tabella e da tabella a oggetto. Una volta che puoi scrivere il tuo modello di dati in un unico posto, diventa più facile aggiornare, mantenere e riutilizzare il codice.

Poiché il modello è debolmente associato al resto dell'applicazione, è possibile modificarlo senza alcuna dipendenza rigida con altre parti dell'applicazione e può essere facilmente utilizzato ovunque all'interno dell'applicazione. TypeORM è molto flessibile, astrae il sistema DB dall'applicazione e ci consente di trarre vantaggio dall'uso del concetto OOPS.

Panoramica

TypeORM è una libreria Object Relational Mapper in esecuzione in node.js e scritta in TypeScript. TypeScript è un miglioramento di JavaScript con la digitazione opzionale. TypeScript è un linguaggio compilato. Non viene interpretato in fase di esecuzione. Il compilatore TypeScript accetta i file TypeScript (.ts) e li compila in file JavaScript (.js).

TypeORM supporta più database come MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana e WebSQL. TypeORM è un ORM facile da usare per impacchettare nuove app che si connettono ai database. La funzionalità TypeORM è concetti specifici di RDBMS.

Possiamo creare rapidamente nuovi progetti e micro-servizi. Si ispira a strumenti simili come Hibernate, Doctrine, Entity framework, ecc., Da altri linguaggi di programmazione.

Caratteristiche di TypeORM

TypeORM è dotato delle seguenti caratteristiche:

  • Crea automaticamente schemi di tabelle di database basati sui tuoi modelli.
  • Inserisci, aggiorna ed elimina facilmente oggetti nel database.
  • Crea mapping (uno a uno, uno a molti e molti a molti) tra le tabelle.
  • Fornisce semplici comandi CLI.

Vantaggi di TypeORM

TypeORM è un framework ORM facile da usare con una semplice codifica. Ha i seguenti vantaggi:

  • Applicazioni di alta qualità e ad accoppiamento lasco.
  • Applicazioni scalabili.
  • Si integra facilmente con altri moduli.
  • Si adatta perfettamente a qualsiasi architettura, dalle app piccole a quelle aziendali.

Questo capitolo spiega come installare TypeORM sulla macchina. Prima di passare all'installazione, assicurati che npm sia installato. Per confermare di avere npm, puoi eseguire il seguente comando nel tuo terminale.

npm -v

Mostra la versione. Se non è installato, scarica l'ultima versione e installala sul tuo computer.

Installa TypeORM

Installiamo TypeORM localmente usando il modulo npm -

npm install typeorm --save

Dopo aver eseguito il comando precedente, riceverai una risposta come indicato di seguito:

+ [email protected] 
+ 
added 1 package and audited 1236 packages in 4.729s

In alternativa, per installare TypeORM a livello globale, utilizzare il comando seguente:

npm install typeorm -g

Successivamente, installa il pacchetto opzionale reflection-metadata utilizzando npm -

npm install reflect-metadata --save

Potresti vedere la seguente risposta:

+ [email protected] 

added 1 package and audited 1236 packages in 2.426s

Ora installa un altro pacchetto opzionale. digitazioni di nodi utilizzando il comando seguente:

npm install @types/node --save

Potresti vedere la seguente risposta:

+ @types/[email protected] 

added 1 package and audited 1236 packages in 2.167s

Installa il driver del database

In questa sezione, installiamo i pacchetti del nodo necessari per il nostro database.

Installare MySQL o MariaDB pacchetto, usa il comando seguente -

npm install mysql --save

Potresti vedere la seguente risposta:

+ [email protected] 

added 1 package and audited 1236 packages in 4.36s

Installare PostgreSQL pacchetto, usa il comando seguente -

npm install pg --save

Potresti vedere la seguente risposta:

+ [email protected] 

added 1 package and audited 1236 packages in 2.863s

Installare SQLite pacchetto, usa il comando seguente -

npm install sqlite3 --save

Potresti vedere la seguente risposta:

+ [email protected] 
added 48 packages from 45 contributors and audited 1396 packages in 7.31s

Installare Microsoft SQL Server pacchetto, usa il comando seguente -

npm install mssql --save

Il tuo schermo è simile a questo,

+ [email protected] 

added 1 package and audited 1655 packages in 2.378s

Installare sql.js pacchetto, usa il comando seguente -

npm install sql.js --save

Potresti vedere la seguente risposta:

+ [email protected] 

added 1 package and audited 1655 packages in 6.462s

Installare Oracle server pacchetto, usa il comando seguente -

npm install oracledb --save

Potresti vedere la seguente risposta:

+ [email protected] 

added 1 package and audited 1655 packages in 2.265s

Installare mongodb pacchetto, usa il comando seguente -

npm install mongodb --save

Potresti vedere la seguente risposta:

+ [email protected] 

added 1 package and audited 1655 packages in 3.716s

Questo capitolo spiega come creare una semplice applicazione TypeORM. Creiamo una nuova directory denominata "TypeORM" e spostiamoci nella directory.

cd /path/to/TypeORM/

Sintassi

Usa il comando seguente per creare un nuovo progetto -

typeorm init --name <project-name> --database <database-name>

Esempio

typeorm init --name FirstProject --database mysql

Qui,

FirstProject è il nome del tuo progetto e sqlite3è il nome del database. Dopo aver eseguito il comando precedente, potresti vedere la seguente risposta,

Project created inside /path/to/TypeORM/FirstProject directory

Ora, spostati nella nostra directory del progetto e installa le dipendenze del progetto usando npm modulo,

$ cd FirstProject $ npm install

Struttura del progetto

Cerchiamo di capire la struttura del nostro progetto di nuova creazione, FirstProject.

FirstProject 
├──> src 
│ ├──> entity 
│ │ └──> User.ts 
│ ├──> migration 
│ └──> index.ts 
├──> node_modules 
├──> ormconfig.json 
├──> package.json 
├──> package-lock.json 
└──> tsconfig.json

Qui,

  • src - contiene il codice sorgente della tua applicazione in formato TypeScriptlinguaggio. Ha un fileindex.ts e due sottodirectory entity e migration.
  • index.ts - Il tuo punto di accesso all'applicazione.
  • entity - Contiene modelli di database.
  • migration - contiene il codice di migrazione del database.
  • node_modules - moduli npm salvati localmente.
  • ormconfig.json- File di configurazione principale della tua applicazione. Contiene i dettagli di configurazione del database e la configurazione delle entità.
  • package.json - Contiene le dipendenze del modulo del nodo.
  • package-lock.json - File generato automaticamente e relativo a package.json.
  • tsconfig.json - Contiene le opzioni del compilatore specifiche di TypeScript.

file ormconfig.json

Controlliamo l'opzione di configurazione disponibile per la nostra applicazione. Apri il file ormconfig.json e sembra simile a questo -

{ 
   "type": "mysql", 
   "host": "localhost", 
   "port": 3306, 
   "username": "test", 
   "password": "test", 
   "database": "test", 
   "synchronize": true, 
   "logging": false, 
   "entities": [ 
      "src/entity/**/*.ts" ], 
   "migrations": [ "src/migration/**/*.ts" 
   ], 
   "subscribers": [ "src/subscriber/**/*.ts" 
   ], 
   "cli": { 
      "entitiesDir":"src/entity", "migrationsDir":"src/migration", "subscribersDir":"src/subscriber
   }    
 }

Qui,

type, host, username, password, database e le opzioni della porta sono correlate all'impostazione del database. mysql può essere configurato utilizzando la configurazione seguente -

{ 
   "type": "mysql", 
   "host": "localhost", 
   "port": 3306, 
   "username": "db_username", "password": "db_password", "database": "db_name" 
}
  • entities - fa riferimento alla posizione delle classi di entità.
  • migrations - fa riferimento alla posizione delle tue classi di migrazione.
  • subscribers - fa riferimento alla posizione delle classi di iscritti.
  • cli - fa riferimento all'opzione utilizzata da TypeORM CLI per generare automaticamente il codice

Avvia il server MySql

Prima di avviare l'applicazione, avvia il tuo MySQL server o qualsiasi server di database da te utilizzato e assicurati che funzioni correttamente.

Esegui l'applicazione

Una volta che tutto è configurato, possiamo eseguire l'applicazione utilizzando il comando seguente:

npm start

Potresti vedere la seguente risposta:

> [email protected] start /Users/../../TypeORM/FirstProject 

> ts-node src/index.ts 

Inserting a new user into the database... Saved a new user with id: 1 Loading users from the database... Loaded users: [ User { id: 1, firstName: 'Timber', lastName: 'Saw', age: 25 }] 

Here you can setup and run express/koa/any other framework.

L'applicazione ha inserito un nuovo utente nel database, quindi lo carica in senso inverso dal database e infine mostra l'utente caricato nella console. Abbiamo creato con successo un nuovo fileTypeORM applicazione, configurarla ed eseguire l'applicazione.

Discuteremo di come i dati vengono elaborati nei prossimi capitoli.

Per interagire con il database, abbiamo bisogno di un oggetto di connessione al database. È necessario creare un oggetto di connessione prima di eseguire l'operazione sul database e terminarlo una volta completate le operazioni sul database. Impariamo a conoscere l'API di connessione fornita da TypeORM in questa sezione.

Creazione di una nuova connessione

Prima di creare una nuova connessione, è necessario configurare i dettagli della connessione al database nel file ormconfig.jsonfile di configurazione. Di seguito vengono mostrati i dettagli della connessione di esempio:

ormconfig.json

{ 
   name: "firstconnection", 
   type: "mysql", 
   host: "localhost", 
   port: 3306, 
   username: "root", 
   password: "root", 
   database: "firstDB" 
}

Qui,

  • name - Nome della connessione al database.
  • type - Tipo di database.
  • host - Nome host del server del database.
  • port - Porta del server del database.
  • username - Nome account che ha accesso al database.
  • password - Password dell'account sopra menzionato.
  • database - Nome del database a cui connettersi.

createConnection

CreateConnectionè fornito da TypeORM per creare una nuova connessione. È definito come di seguito,

import { createConnection, Connection } from "typeorm"; 

const connection = await createConnection({ 

});

Qui, createConnection utilizzerà i dettagli di configurazione specificati nel file ormconfig.json.

In alternativa, puoi definire l'URL di connessione come argomenti per il metodo createConnection come specificato di seguito:

const connection = createConnection({ type: 'mysql', 
     url: 'localhost:8888/firstDB' 
})

Qui,

createConnection restituisce un oggetto, che può essere utilizzato per aprire / chiudere la connessione al database.

Connessioni multiple

TypeORM fornisce anche un'opzione per creare più connessioni a database. Innanzitutto, è possibile utilizzare il file di configurazione ormconfig.json per specificare i dettagli della connessione a più database. Configuriamo più database in ormconfig.json come specificato di seguito,

ormconfig.json

{  name: "firstconnection", 
   type: "mysql", 
   host: "localhost", 
   port: 3306, 
   username: "root", 
   password: "root", 
   database: "firstDB" 
}, 
{  name: "secondconnection", 
   type: "mysql", 
   host: "localhost", 
   port: 3306, 
   username: "root", 
   password: "root", 
   database: "secondDB" 
}, 
{  name: "thirdconnection", 
   type: "mysql", 
   host: "localhost", 
   port: 3306, 
   username: "root", 
   password: "root", 
   database: "thirdDB" 
}

Ora, possiamo usare l'argomento fornito dal metodo createConnection per specificare il nome della connessione per creare l'oggetto connessione come menzionato di seguito -

const firstconnection: Connection = await createConnection("firstconnection");

Qui,

createConnection utilizzerà i dettagli di configurazione del file firstconnection specificato nel ormconfig.json file per creare l'oggetto connessione.

TypeORM fornisce anche un'altra API, createConnections per creare più connessioni come una volta e poi, usala ogni volta che è necessario come specificato di seguito -

import { createConnections, Connection } from "typeorm"; 

const connections: Connection[] = await createConnections([ 

]);

Qui,

connections tenere tutti gli oggetti di connessione come un array.

ConnectionManager

TypeORM fornisce anche un'altra API, connectionManager per creare la connessione. È definito di seguito:

import {getConnectionManager, ConnectionManager, Connection} from "typeorm"; 

const connectionManager = getConnectionManager(); 

const connection = connectionManager.create({ 

}); 
await connection.connect();

TypeORM preferisce l'utilizzo di createConnection al di sopra di ConnectionManager per creare oggetti di connessione.

Un'entità è una raccolta di campi e operazioni di database associate. Viene utilizzato per mappare la tabella del database e i suoi campi con le entità e i suoi attributi. Questo capitolo spiega in dettaglio le entità TypeORM.

introduzione

Creiamo una semplice classe Entity nel nostro codice. Spostati nella posizione principale del tuo progetto e vai nella cartella src e spostati nella cartella delle entità. Ora, crea un file TypeScript, Student.ts e inserisci il codice sottostante -

Student.ts

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm"; 

@Entity() 
export class Student {   

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   Name: string; 
   
   @Column() 
   age: number; 
}

Qui,

  • Entity() La classe decorator viene utilizzata per rappresentare che il file Student class è un'entità.
  • PrimaryGeneratedColumn() La classe decorator viene utilizzata per rappresentare che la colonna id è la colonna chiave primaria di Student entità.
  • Column() La classe decorator viene utilizzata per rappresentare altre colonne come Name e Age del Student entità.

Ora, classe Entity Studentè creato. TypeORM genererà automaticamente una tabella corrispondente al fileStudent entità nel nostro database e sarà denominata come student. Ora passa asrc/index.ts file e aggiungi il seguente codice -

index.ts

import "reflect-metadata"; 
import {createConnection} from "typeorm";
import {Student} from "./entity/Student"; //import Student entity

createConnection().then(async connection => { 

   console.log("Inserting a new record into the student database..."); 
   
   //create student object const stud = new Student(); 
   
   //Assign student name and age here stud.Name = "student1"; 
   stud.age = 12; 
   
    //save student object in connection await connection.manager.save(stud); console.log("Saved a new user with id: " + stud.id);
    
    console.log("Loading users from the database...");

    //Display student saved records const students = await connection.manager.find(Student); console.log("Loaded users: ", students);

    console.log("Here you can setup and run express/koa/any other framework.");
}).catch(error => console.log(error));

Qui,

  • La riga 1-3 importa le classi rilevanti, createConnection e Student
  • La riga 5 crea una nuova connessione al database utilizzando createConnection e se viene stabilita la connessione, esegue il codice all'interno del file then bloccare.
  • Riga 10 crea un nuovo oggetto Studente, perno.
  • La riga 13-14 imposta gli attributi del nostro oggetto perno appena creato.
  • La riga 17 salva l'entità nel database utilizzando il metodo di salvataggio disponibile in connection.manager oggetto.
  • La riga 23 recupera i dettagli dello studente dal database utilizzando il metodo find disponibile in connection.manager oggetto.

Avvia il server Mysql ed esegui la tua applicazione

Abbiamo creato l'entità Student e creato la connessione in index.ts. Avviamo sia il server MySql che la tua applicazione.

npm start

Questo restituirà il seguente output sullo schermo:

Produzione

Aperto mysql server che segue student tabella viene aggiunta all'interno del database.

Colonne

Come appreso in precedenza, Entity è in realtà una raccolta di attributi. Come oggetto entità fa riferimento alla tabella del database. I suoi attributi / variabili membro fanno riferimento ai campi / colonne della tabella del database corrispondente. TypeORM supporta tutti i tipi di campi di database tramite la classe Column. Impariamo il diverso tipo di colonna supportato da TypeORM in questo capitolo.

@Column() La classe decorator viene utilizzata per rappresentare la colonna e il suo tipo nell'entità.

Ad esempio, l'attributo età dell'entità studente e il tipo di attributo età possono essere definiti come di seguito:

@Column("int") age: integer; // OR @Column({ type: "int" }) age: integer;

Qui,

  • ageè l'attributo dell'entità. In altre parole, l'età è un campo / colonna nella tabella degli studenti nel database.
  • int rappresentano il tipo di colonna età nel database.

TypeORM supporta quasi tutti i tipi disponibili nel popolare motore di database. In realtà, TypeORM abilita diversi set di tipi per ogni motore di database. Possiamo utilizzare qualsiasi tipo di database supportato dal nostro motore di database senza alcun problema.

Ad esempio, il tipo supportato da TypeORM per il motore di database postgresql è il seguente:

int, int2, int4, int8, smallint, integer, bigint, decimal, numeric, real, float, float4, float8, double precision, money, character varying,

varchar, character, char, text, citext, hstore, bytea, bit, varbit, bit

varying, timetz, timestamptz, timestamp, timestamp without time zone, timestamp with time zone, date, time, time without time zone, time with time zone, interval, bool, boolean, enum, point, line, lseg, box, path, polygon, circle, cidr, inet, macaddr, tsvector, tsquery, uuid, xml, json, jsonb, int4range, int8range, numrange, tsrange, tstzrange, daterange, geometry, geography, cube

Allo stesso modo, TypeORM supporta un diverso set di tipi di dati per MySQL.

Opzioni colonna

TypeORM fornisce un ampio insieme di opzioni diverse dal tipo per descrivere la colonna. Ad esempio, l'opzione lunghezza si riferisce alla lunghezza del campo del database e può essere specificata come di seguito:

@Column("varchar", { length: 100 })

Alcune delle opzioni di colonna più comuni sono le seguenti:

  • name - Nome del campo / colonna del database.
  • length - Lunghezza del campo / colonna del database.
  • nullable - Specificare se il campo / colonna del database consente null o meno.
  • default - Valore predefinito del campo / colonna del database.
  • primary - Specificare se il campo / colonna del database è la chiave primaria della tabella.
  • unique - Specificare se il campo / colonna del database è univoco
  • *precision** - Precisione del campo / colonna del database
  • scale - Scala del campo / colonna del database
  • comment - Commento o descrizione del campo / colonna del database

@Generated decoratore

TypeORM fornisce un decoratore aggiuntivo, @Generated per generare automaticamente i valori delle colonne. Ad esempio, Universally Unique Identifier (UUID) è abbastanza comune da utilizzare nel database per memorizzare un valore univoco in una colonna. Il codice di esempio per generare l'UUID è il seguente:

@Entity() 
export class Student {
 
   @PrimaryColumn() 
   id: number; 
   
   @Column() 
   @Generated("uuid") 
   uuid: string; 
}

Qui,

uuid viene generato automaticamente e memorizzato all'interno del database.

Colonne primarie

Almeno un campo della colonna primaria è obbligatorio per qualsiasi entità nel database. È classificato in diversi tipi di decoratori. Ne discuteremo uno per uno.

@PrimaryColumn()

Il decoratore @PrimaryColumn () viene utilizzato per creare la colonna primaria per qualsiasi tipo di dati. Di seguito è mostrato un semplice esempio,

import {Entity, PrimaryColumn} from "typeorm"; 

@Entity() 
export class Student {        
@PrimaryColumn() 
   id: number; 
}

Qui,

id è un numero intero, che non accetta valori duplicati, ma è necessario assegnare valori.

Possiamo anche assegnare la colonna primaria a uno o più campi, se la situazione lo richiede.

Esempio

import {Entity, PrimaryColumn} from "typeorm"; 

@Entity() 
export class Student { 
   
   @PrimaryColumn() 
   id: number; 
   
   @PrimaryColumn() 
   email: string; 
   
   @PrimaryColumn() 
   phone: number; 
}

@PrimaryGeneratedColumn ()

@PrimaryGeneratedColumn()viene utilizzato per specificare la colonna primaria e per generare automaticamente il valore della colonna nel database. È mostrato di seguito -

import {Entity, PrimaryGeneratedColumn} from "typeorm"; 

@Entity() 
export class Student {

   @PrimaryGeneratedColumn() 
   id: number;
}

Qui,

Non è necessario assegnare un valore id; sarà generato automaticamente dal TypeORM nella tabella del database.

@PrimaryGeneratedColumn ("uuid")

@PrimaryGeneratedColumn accetta anche un argomento per specificare il tipo di generatore. Uno degli utilizzi principali è generare un ID univoco basato sull'UUID.

import {Entity, PrimaryGeneratedColumn} from "typeorm";

@Entity() 
export class Student {  
   @PrimaryGeneratedColumn("uuid") id: string; 
}

tipo di colonna array semplice

Il database relazionale avanzato supporta il tipo di dati dell'array. Per supportare il tipo di dati dell'array, TypeORM fornisce un tipo di colonna speciale, * simple-array "per memorizzare i valori dell'array primitivo. Un codice di esempio per utilizzarlo è il seguente:

@Entity() 
export class Student { 
   
   @PrimaryGeneratedColumn() 
   id: number;

   @Column("simple-array") 
   names: string[]; 
}

tipo di colonna simple-json

Molti moderni motori di database supportano il database JSON. Per utilizzare il tipo di dati JSON, TypeORM fornisce un tipo speciale, single-json. Il codice di esempio da utilizzare è il seguente:

@Entity() 
export class Student { 

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column("simple-json")
   info: { firstName: string, middleName: string, lastName: string }; 
}

Questo valore può essere definito in index.ts come,

index.ts

const stud = new Student(); 
stud.info = { firstName: "John", middleName: "peter", lastName: "Michael" };

Colonne speciali

TypeORM supporta le seguenti colonne speciali

  • @CreateDateColumn - È una colonna speciale per impostare automaticamente la data di inserimento dell'entità.
  • @UpdateDateColumn - Viene utilizzato per impostare automaticamente l'ora di aggiornamento dell'entità.
  • @VersionColumn - Imposta automaticamente il numero di versione per l'entità.

Ereditarietà delle entità

L'ereditarietà delle entità viene utilizzata per ridurre la duplicazione delle entità. Considera le entità seguenti:

Result.ts

@Entity() 
export class Result {    

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   title: string; 
   
   @Column() 
   description: string; 
   
   @Column() 
   eligible: string 
}

Grade.ts

Il codice per grade.ts è il seguente:

@Entity() 
export class Grade {

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   name: string; 
   
   @Column() 
   title: string; 
   
   @Column() 
   description: string;
   
   
   
   @Column() 
   grading : string; 
}

Qui,

Le due entità precedenti hanno colonne id, titolo e descrizione. Usando l'ereditarietà delle entità, creiamo una classe di base Dettagli e combiniamo le due entità sopra come specificato di seguito.

Dettagli.ts

export abstract class Details {

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   title: string; 
   
   @Column() 
   description: string; 
} 
@Entity() 
export class Result extends Details{  

   @Column() 
   eligible: string 
} 
@Entity() 
export class Grade extends Details{   

   @Column() 
   name : string; 
   
   @Column() 
   grading : string; 
}

Ora avvia il tuo server, potresti vedere la risposta di seguito,

Ora apri il tuo server mysql e spostati nel tuo database, potresti vedere le seguenti tabelle,

Tabella dei voti

Tabella dei risultati

Le relazioni vengono utilizzate per fare riferimento alla relazione tra la tabella nel database. In generale, esiste una relazione tra due tabelle quando una di esse ha una chiave esterna che fa riferimento alla chiave primaria dell'altra tabella. Questa funzione rende il database relazionale più potente e archivia le informazioni in modo efficiente.

TypeORM consente alle entità di essere correlate tra loro e successivamente tabelle di database. In generale, la relazione può essere classificata in quattro categorie più ampie. Sono i seguenti,

one-to-one- Un oggetto dell'entità data si riferisce a un solo oggetto dell'entità target e viceversa. Ad esempio, un paese avrà solo una capitale e allo stesso modo una città sarà capitale di un solo paese.

many-to-one- Più oggetti dell'entità data si riferiscono a un oggetto dell'entità target. Ad esempio, la città rientra in un solo paese, ma il paese può avere più città.

one-to-many - Come molti-a-uno tranne per il fatto che la relazione è invertita.

many-to-many- L'oggetto multiplo di una determinata entità si riferisce a più oggetti dell'entità di destinazione. Ad esempio, un articolo può essere taggato in più argomenti come linguaggio di programmazione, finanza, ecc. E allo stesso tempo un tag particolare può avere anche più articoli.

TypeORM fornisce anche opzioni per migliorare la relazione tra le entità. Sono i seguenti:

  • eager - L'oggetto entità di origine carica anche gli oggetti entità di destinazione.
  • cascade - L'oggetto entità di destinazione viene inserito o aggiornato mentre l'oggetto entità di origine viene inserito o aggiornato.
  • onDelete - Anche gli oggetti entità di destinazione vengono eliminati mentre viene eliminato l'oggetto entità di origine.
  • primary - Utilizzato per specificare che la colonna della relazione è o meno la chiave primaria.
  • nullable - Utilizzato per specificare che la colonna della relazione è annullabile o meno.

Esaminiamo in dettaglio diversi tipi di mappatura delle relazioni.

Uno a uno

Come abbiamo appreso in precedenza, viene indicato dall'istanza di un campo di tabella contenente l'istanza di un altro campo di tabella e viceversa. Creiamo un fileDetails tavolo -

Dettagli.ts

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";

@Entity() 
export class Details {
   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   gender: string; 
   
   @Column() 
   country: string; 
}

Creiamo un'altra entità Cliente come segue:

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;
}

Qui,

Abbiamo aggiunto la mappatura OneToOne per Details tavolo. @JoinColumn() contenere un "id relazione" e una chiave esterna per Customertavolo. Possiamo salvare la relazione inindex.ts come 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);

Uno-a-molti e molti-a-uno

Come abbiamo appreso in precedenza, viene indicato dall'istanza del primo campo della tabella che contiene più istanze del secondo campo della tabella chiamato One-to-Many mapping e più istanze della prima tabella contiene solo un'istanza della seconda tabella chiamata Many-to-One Mappatura.

Considera un esempio di Student e project entità mentre lo studente può lavorare su più di un progetto ma ogni progetto è gestito da un solo studente.

Creiamo un file Project entità come segue -

Progetto

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; 
}

Ora creiamo Student entità come di seguito -

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[];  
}

Qui,

@OneToMany proprietà mappata Project e @ManyToOne proprietà mappata a Student. Però,@OneToMany non può esistere senza @ManyToOne e @ManyToOne la proprietà contiene "id relazione" e chiave esterna.

Possiamo salvare la connessione in index.ts come 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);

Molti a molti

Come abbiamo appreso in precedenza, viene indicato da più record in una tabella che sono correlati a più record in un'altra tabella. Considera un esempio, uno studente universitario può essere iscritto a più classi contemporaneamente, il che significa che lo studente può avere quattro o cinque classi per semestre e una classe può avere molti studenti.

Possiamo semplicemente concludere, uno studente ha molte classi e una classe ha molti studenti. Creiamo un'entità perClasses come segue -

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm"; 

@Entity() 
export class Classes { 

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   name: string; 
}

Ora creiamo Student entità come di seguito -

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[];
}

Il repository è specifico di un'entità. In altre parole, ogni entità avrà il proprio repository integrato ed è possibile accedervi utilizzando il metodo getRepository () dell'oggetto di connessione come specificato di seguito -

const studRepository = manager.getRepository(Student);

Una volta creato l'oggetto repository studente, può essere utilizzato per eseguire tutte le operazioni di database dell'oggetto studente.

Tipi di repository

Repositoryè classificato in quattro categorie. Sono i seguenti:

Repository

Repository predefinito di un'entità ed è possibile accedervi utilizzando getRepository() metodo come specificato di seguito -

const studRepository = manager.getRepository(Student);

Adesso, studRepository può essere utilizzato per interrogare la tabella degli studenti

TreeRepository

Utilizzato per entità struttura ad albero ed è possibile accedervi utilizzando getTreeRepository() metodo come specificato di seguito -

const studcaRepository = manager.getTreeRepository(Student);

MongoRepository

Utilizzato all'interno delle entità operative di mongoDB ed è possibile accedervi utilizzando getMongoRepository() metodo come specificato di seguito -

const detailsRepository = manager.getMongoRepository(Details);

CustomRepository

Utilizzato per personalizzare il repository ed è possibile accedervi utilizzando getCustomRepository() metodo come specificato di seguito,

const myUserRepository = manager.getCustomRepository(UserRepository);

API del repository

Impariamo il metodo più importante di EntityManager in questo capitolo.

manager

Possiamo accedere EntityManager utilizzando il metodo manager come specificato di seguito -

const manager = repository.manager;

queryRunner

queryRunnerrestituisce un oggetto runner di query personalizzato e viene utilizzato per le operazioni di database dal repository. Il codice di esempio è il seguente:

const queryRunner = repository.queryRunner;

metadati

metadatarestituisce i metadati del repository. Il codice di esempio è il seguente:

const metadata = repository.metadata;

query

querymetodo esegue query SQL. Query di selezione semplice come mostrato di seguito -

const qur = await repository.query(`select * from students`);

inserire

insertviene utilizzato per inserire una nuova entità o un array di entità nel database. Il codice di esempio è il seguente:

await repository.insert({ 
   Name: "Student3", 
   Age: 14 
});

La query sopra è equivalente a,

insert into student(Name,age) values("Student3",14)

aggiornare

update viene utilizzato per aggiornare i record esistenti nel database.

await repository.update(1, { Name: "Adam" });

Questa query funziona in modo simile a quella menzionata di seguito:

update student SET Name = "Adam" where id = 1

Elimina

delete il metodo eliminerà il record specificato dalla tabella,

await repository.delete(Student, 1);

Questo eliminerà lo studente con ID 1 dal studenttavolo. È equivalente a,

delete from student where id=1;

Se desideri eliminare per nome, utilizza la query seguente,

await repository.delete({ Name: "Student1" });

Questa query eliminerà tutti gli studenti con nome, Student1

** softDelete e ripristina **

Viene utilizzato per eliminare gradualmente i dati ed è possibile ripristinare il record in base all'ID dello studente. Il codice di esempio è il seguente:

await repository.softDelete(1);

Puoi ripristinare il record dello studente usando il comando seguente:

await repository.restore(1);

Un'opzione alternativa per eliminare e ripristinare è usare softRemove e recovermetodi. Il codice di esempio è il seguente:

//find the entities const enty = await repository.find(); 

//soft removed entity const entySoftRemove = await repository.softRemove(enty);

E puoi recuperarli utilizzando il metodo di recupero come specificato di seguito,

await repository.recover(entySoftRemove);

Salva

saveviene utilizzato per salvare l'entità data nel database. L'entità studente semplice può essere salvata come mostrato di seguito:

import {Student} from "./entity/Student"; 

createConnection().then(async connection => {                     
   console.log("Inserting a new record into the student database..."); 
   const stud = new Student();
   stud.Name = "student1"; 
   stud.age = 12; 
   await repository.save(stud);

Ciò aggiungerà il nuovo record dello studente nel database.

rimuovere

removeviene utilizzato per eliminare l'entità specificata dal database. L'entità Studente semplice può essere eliminata come mostrato di seguito:

await repository.remove(stud);

contare

countrestituirà il numero di record disponibili nella tabella e potrai utilizzarlo per scopi di impaginazione. Il codice di esempio è il seguente:

const cnt = await repository.count(Student, { age: 12 });

trova

findmetodo viene utilizzato per scopi di ricerca. Recupera tutto il record dal database come mostrato di seguito -

const result = await repository.find({ id: 1 });

trova uno

Simile a findmetodo, ma restituisce il primo record corrispondente. Il codice di esempio è il seguente:

const result = await repository.findOne({ id: 1 });

chiaro

clearil metodo cancella tutti i dati dalla tabella. Il codice di esempio è il seguente:

await repository.clear();

EntityManager è simile a Repositorye utilizzato per gestire le operazioni del database come inserire, aggiornare, eliminare e caricare i dati. MentreRepository gestisce una singola entità, EntityManager è comune a tutte le entità e in grado di eseguire operazioni su tutte le entità.

API Entity Manager

Possiamo accedere EntityManager utilizzando getManager() metodo come specificato di seguito -

import { getManager } from "typeorm"; const entityManager = getManager();

Impariamo il metodo più importante di EntityManager in questo capitolo.

connessione

connectionrestituisce la connessione ORM del database a database specifici. Il codice di esempio è il seguente:

const connection = manager.connection;

QueryRunner

queryRunnerrestituisce un oggetto runner di query personalizzato ed è utilizzato per le operazioni di database da entity manager. Il codice di esempio è il seguente:

const queryRunner = manager.queryRunner;

transazione

Se vengono chiamate più richieste di database, la transazione verrà eseguita in una singola transazione di database. Il codice di esempio per ottenere la transazione è il seguente:

await manager.transaction(async manager => { 
});

query

querymetodo esegue query sql. Semplice query di inserimento come mostrato di seguito -

const qur = await manager.query(`insert into student(name,age) values('stud2',13)`);

inserire

insertviene utilizzato per inserire una nuova entità o un array di entità nel database. Il codice di esempio è il seguente:

await manager.insert(Student, { 
   Name: "Student3", 
   Age: 14 
});

aggiornare

update viene utilizzato per aggiornare i record esistenti nel database.

await manager.update(User, 1, { Name: "Adam" });

Questa query funziona in modo simile alla query SQL seguente,

UPDATE student SET Name = "Adam" WHERE id = 1

Elimina

il metodo delete eliminerà il record specificato dalla tabella,

await manager.delete(Student, 1);

Verranno eliminati con l'ID 1 del record dello studente.

Salva

saveviene utilizzato per salvare l'entità data nel database. L'entità studente semplice può essere salvata come mostrato di seguito:

import {Student} from "./entity/Student";

createConnection().then(async connection => {   
   console.log("Inserting a new record into the student database..."); 
   const stud = new Student(); stud.Name = "student1"; 
   stud.age = 12; 
   await connection.manager.save(stud); 
}

Ciò aggiungerà il nuovo record dello studente nel database. Il metodo save inserirà lo studente, se lo studente specificato non esiste nel database. In caso contrario, il salvataggio aggiornerà il record dello studente esistente nel database.

rimuovere

removeviene utilizzato per eliminare l'entità specificata dal database. L'entità Studente semplice può essere eliminata come mostrato di seguito:

await manager.remove(stud);

contare

countrestituirà il numero di record disponibili nella tabella e potrai utilizzarlo per scopi di impaginazione. Il codice di esempio è il seguente:

const cnt = await manager.count(Student, { age: 12 });

trova

findmetodo viene utilizzato per scopi di ricerca. Recupera tutto il record dal database come mostrato di seguito -

console.log("Loading users from the database..."); 
const students = await connection.manager.find(Student); console.log("Loaded users: ", students);

trova uno

Simile a findmetodo, ma restituisce il primo record corrispondente. Il codice di esempio è il seguente:

const stud = await manager.findOne(Student, 1);

chiaro

Il metodo clear cancella tutti i dati dalla tabella. Il codice di esempio è il seguente:

await manager.clear(Student);

Il generatore di query viene utilizzato per creare query SQL complesse in modo semplice. Viene inizializzato dal metodo Connection e dagli oggetti QueryRunner.

Possiamo creare QueryBuilder in tre modi.

Connessione

Considera un semplice esempio di come utilizzare QueryBuilder utilizzando il metodo di connessione.

import {getConnection} from "typeorm"; 

const user = await getConnection() .createQueryBuilder() 
.select("user") 
.from(User, "user") 
.where("user.id = :id", { id: 1 }) .getOne();

Responsabile entità

Creiamo un generatore di query utilizzando il gestore entità come segue:

import {getManager} from "typeorm"; 

const user = await getManager() .createQueryBuilder(User, "user") .where("user.id = :id", { id: 1 })    .getOne();

Repository

Possiamo usare il repository per creare un generatore di query. È descritto di seguito,

import {getRepository} from "typeorm"; 

const user = await getRepository(User) .createQueryBuilder("user") .where("user.id = :id", { id: 1 }) .getOne();

Alias

Gli alias sono gli stessi dell'alias SQL. Creiamo alias per la tabella Studente utilizzando QueryBuilder come descritto di seguito -

import {getConnection} from "typeorm"; 

const user = await getConnection() .createQueryBuilder() 
.select("stud") 
.from(Student, "stud")

Questa query è equivalente a,

select * from students as stud

Parametri

Parametersvengono utilizzati come segnaposto per i valori dinamici nella query. In molti casi, la query per trovare un oggetto entità diverso sarà la stessa tranne i valori. Ad esempio, la query per trovare uno studente diverso è la stessa tranne il fileStudent IDdati. In questo caso, possiamo usare il parametro perStudent ID e quindi modificare il parametro per ottenere i diversi oggetti studente.

Un altro uso importante del parametro è prevenire l'iniezione SQL. È una delle più importanti falle di sicurezza nelle moderne applicazioni web. Utilizzando il parametro nella query, possiamo sopravvivere agli attacchi di SQL injection.

Un altro uso importante del parametro è prevenire l'iniezione SQL. È una delle più importanti falle di sicurezza nelle moderne applicazioni web. Utilizzando il parametro nella query, possiamo sopravvivere agli attacchi di SQL injection.

Per esempio

"student.id = :id", { id: 1 }

Qui,

: id - nome del parametro.

{id: 1} - valore del parametro

Aggiunta di espressione

Questa sezione spiega come utilizzare le espressioni.

dove

where viene utilizzato per filtrare i record se la condizione viene soddisfatta.

createQueryBuilder("student") .where("student.id = :id", { id: 1 })

Questa query è equivalente a,

select * from students student where student.id=1;

Possiamo anche usare le condizioni AND, OR, NOT, IN all'interno.

avendo

L'espressione semplice è definita di seguito:

createQueryBuilder("student") .having("student.id = :id", { id: 1 })

Questa query è equivalente a,

select * from students student having student.id=1;

ordinato da

orderby viene utilizzato per ordinare i record in base al campo.

createQueryBuilder("student") .orderBy("student.name")

Questa query è equivalente a,

select * from students student order by student.name;

raggruppa per

Viene utilizzato per raggruppare i record in base alla colonna specificata.

createQueryBuilder("student") .groupBy("student.id")

Questa query è equivalente a,

select * from students student group by student.id;

limite

Viene utilizzato per limitare la selezione delle righe. Di seguito, l'esempio mostra come utilizzare il limite nel generatore di query,

createQueryBuilder("student") .limit(5)

Questa query è equivalente a,

select * from students student limit 5;

compensare

L'offset viene utilizzato per specificare quante righe saltare il risultato. È definito di seguito:

createQueryBuilder("student") .offset(5)

Questa query è equivalente a,

select * from students student offset 5;

si unisce

La clausola join viene utilizzata per combinare righe da due o più tabelle, in base a una colonna correlata. Considera le due entità:

Student.ts

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[]; 
}

Project.ts

import {Entity, PrimaryGeneratedColumn, Column, ManyToOne} from "typeorm"; 
import {Student} from "./Student"; 

@Entity() 
export class Project { 

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   title: string; 
   
   @ManyToOne(type => Student, student => student.projects) student: Student; 
}

Eseguiamo un semplice join sinistro utilizzando la query seguente:

const student = await createQueryBuilder("student") .leftJoinAndSelect("student.projects", "project") 
.where("student.name = :name", { name: "Student1" }) 
.getOne();

Questa query è equivalente a,

SELECT student.*, project.* FROM students student 
   LEFT JOIN projects project ON project.student = student.id 
   WHERE student.name = 'Student1'

Allo stesso modo, possiamo provare anche Inner join.

Partecipa senza selezione

Possiamo unire i dati senza usare select. Proviamo questo esempio usando Inner join come segue:

const student = await createQueryBuilder("student") .innerJoin("student.projects", "project") 
   .where("student.name = :name", { name: "student1" }) 
   .getOne();

La query sopra è equivalente a -

SELECT student.* FROM students student 
   INNER JOIN projects project ON project.student = student.id 
   WHERE student.name = 'Student1';

Impaginazione

Se hai più dati nella tua applicazione, hai bisogno di funzionalità di impaginazione, scorrimento pagina o scorrimento.

Ad esempio, se desideri mostrare i primi cinque progetti degli studenti nella tua domanda,

const students = await getRepository(Student) .createQueryBuilder("student") .leftJoinAndSelect("student.projects", "project") 
   .take(5) 
   .getMany();

sottoquery

Si chiama query all'interno di un'altra query o query annidata. Usiamo sottoquery nelle espressioni FROM, WHERE e JOIN.

Di seguito è mostrato un semplice esempio:

const projects = await connection .createQueryBuilder() .select("project.id", "id")
.addSelect(subQuery => { 
   return subQuery 
      .select("student.name", "name") .from(Student, "student") 
      .limit(1); 
}, "name")
.from(Project, "project") .getMany();

Campo nascosto

Se uno dei campi della colonna è contrassegnato come {select: false}, quella colonna viene considerata come colonna nascosta. Considera l'entità sottostante:

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm"; 

@Entity() 
export class Student {

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   name: string; 
   
   @Column({select: false}) 
   address: string; 
}

Qui,

address il campo è contrassegnato come hidden. Possiamo usareaddSelectmetodo per recuperare le informazioni dalla colonna. È definito di seguito,

const student = await connection.getRepository(Student) .createQueryBuilder() .select("student.id", "student")    .addSelect("student.address") .getMany();

getSql ()

Questo metodo viene utilizzato per ottenere la query SQL generata dal generatore di query. È definito di seguito:

const sql = createQueryBuilder("student") .where("student.name = :name", { name: "Student1" })  .orWhere("student.age = :age", { age: 14 }) 
.getSql();

La manipolazione dei dati viene utilizzata per gestire e visualizzare i dati. Questa sezione spiega come accedere alle query di database come inserire, aggiornare, selezionare ed eliminare le query utilizzando QueryBuilder. Vediamone uno per uno in dettaglio.

Crea query di inserimento

Creiamo un'entità cliente come segue:

Customer.ts

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm"; 
@Entity() 
export class Customer {       

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   name: string; 
   
   @Column() 
   age: number; 
}

Aggiungiamo le seguenti modifiche in index.ts come segue:

index.ts

import "reflect-metadata"; 
import {createConnection} from "typeorm"; 
import {Customer} from "./entity/Customer"; 
import {getConnection} from "typeorm"; 

createConnection().then(async connection => { 
   await getConnection().createQueryBuilder()   .insert() 
      .into(Customer)  
      .values([ { name: "Adam",age:11}, 
         { name: "David",age:12} ]) .execute(); 
}).catch(error => console.log(error));

Ora avvia la tua applicazione usando il comando seguente:

npm start

Produzione

Potresti vedere il seguente output sullo schermo:

Ora apri il tuo server mysql, tabella inserita con due campi come mostrato di seguito -

Crea query di aggiornamento

Nell'ultima sezione, abbiamo inserito due righe di dati. Controlliamo come funziona la query di aggiornamento. Aggiungi le seguenti modifiche in index.ts come segue:

import "reflect-metadata"; 
import {createConnection} from "typeorm"; 
import {Customer} from "./entity/Customer"; 
import {getConnection} from "typeorm";

createConnection().then(async connection => { 

await getConnection()         
   .createQueryBuilder() .update(Customer) 
   .set({ name: "Michael" }) .where("id = :id", { id: 1 }) .execute(); 
   console.log("data updated"); 
   
}).catch(error => console.log(error));

Ora avvia la tua applicazione usando il comando seguente:

npm start

Potresti vedere il seguente output sullo schermo:

La tabella Mysql viene modificata come mostrato di seguito -

Crea query di selezione

selectquery viene utilizzata per visualizzare i record dalla tabella. Aggiungiamo il seguente codice inindex.ts come segue -

index.ts

import "reflect-metadata"; 
import {createConnection} from "typeorm"; 
import {Customer} from "./entity/Customer"; 

createConnection().then(async connection => { 

   console.log("Display records from Customer table..."); 
   const cus = new Customer();

   console.log("Loading customers from the database..."); 
   const customers = await connection.manager.find(Customer); console.log("Loaded users: ", customers); 
}).catch(error => console.log(error));

Potresti vedere il seguente output sullo schermo:

dove espressione

Aggiungiamo l'espressione where nella query per filtrare i clienti. Il codice di esempio è il seguente:

import "reflect-metadata"; 
import {createConnection} from "typeorm"; 
import {Customer} from "./entity/Customer"; 
import {getConnection} from "typeorm";

createConnection().then(async connection => { 
   const customer = await getConnection() .createQueryBuilder() .select("cus") 
   .from(Customer, "cus") .where("cus.id = :id", { id: 1 }) .getOne(); 
   
   console.log(customer); 
})
.catch(error => console.log(error));

Il programma precedente restituirà i primi record di identificazione. Potresti vedere il seguente output sullo schermo,

Allo stesso modo, puoi provare anche altre espressioni.

Crea query di eliminazione

Nell'ultima sezione abbiamo inserito, aggiornato e selezionato i dati. Controlliamo come funziona l'eliminazione della query. Aggiungi le seguenti modifiche in index.ts come segue:

import "reflect-metadata"; 
import {createConnection} from "typeorm"; 
import {Customer} from "./entity/Customer"; 
import {getConnection} from "typeorm"; 

createConnection().then(async connection => { 
   await getConnection() .createQueryBuilder() 
   .delete() 
   .from(Customer) 
   .where("id = :id", { id: 1 }) .execute();
console.log("data deleted"); }).catch(error => console.log(error));

Potresti vedere il seguente output sullo schermo:

E la tua tabella mysql viene modificata come segue:

In generale, la transazione è un'unità logica responsabile dell'esecuzione del recupero e degli aggiornamenti dei dati. Questa sezione spiega in dettaglio le transazioni.

Creazione di transazioni

Possiamo creare una transazione utilizzando la connessione o EntityManage. L'esempio seguente viene utilizzato per specificare la creazione della connessione e salvare i dati al suo interno.

import {getConnection} from "typeorm"; 

await getConnection().transaction(async transactionalEntityManager => { 

   await connection.manager.save(students); 

});

EntityManager è mostrato di seguito -

import {getManager} from "typeorm";

await getManager().transaction(async transactionalEntityManager => { 
   await transactionalEntityManager.save(students); 
});

Decoratori

Abbiamo tre tipi di decoratori relativi alle transazioni in TypeORM.

  • @Transaction - Avvolge tutta l'esecuzione nella singola transazione del database.
  • @TransactionManager- Utilizzato per eseguire query all'interno della transazione. È definito di seguito,
@Transaction({ isolation: "SERIALIZABLE" }) 

save(@TransactionManager() manager: EntityManager, student: Student) {     
   return manager.save(student); 
}

Qui,

Abbiamo usato SERIALIZABLE livello di isolamento per la transazione.

  • @TransactionRepository- Usato per inserire transazioni nel repository. È definito di seguito,
@Transaction() save(student: Student, @TransactionRepository(Student) studentRepository: 
Repository<Student>) { 
   return studentRepository.save(student); 
}

Transazione in QueryRunner

QueryRunner viene utilizzato per eseguire tutte le query di database. Ha una singola connessione al database. La transazione del database può essere organizzata utilizzando QueryRunner . Eseguiamo una singola transazione utilizzando QueryRunner .

import {getConnection} from "typeorm"; 

// get a connection and create a new query runner 
const connection = getConnection(); const queryRunner = connection.createQueryRunner(); 

// establish real database connection using our new query runner 
await queryRunner.connect(); 

// now we can execute any queries on a query runner, for example: await queryRunner.query("SELECT * FROM students");

Ora, avvia la transazione utilizzando l'istruzione seguente:

await queryRunner.startTransaction();

Quindi, eseguire il commit e il rollback della transazione utilizzando l'istruzione seguente,

try { 
   await queryRunner.commitTransaction(); 
}

Se c'è qualche errore, viene gestito da catch (),

catch (err) { 

   // since we have errors lets rollback changes we made await queryRunner.rollbackTransaction(); 
}

Ora rilascia il queryRunner come di seguito:

finally { 
   
   // you need to release query runner which is manually created: await queryRunner.release(); 
}

In generale, Indexingè un processo per ottimizzare le prestazioni di un database ottimizzando l'archiviazione dei dati. Viene utilizzato per individuare e accedere rapidamente ai dati in un database. Questa sezione spiega come utilizzare index in TypeORM. Gli indici sono classificati in diversi tipi. Vediamone uno per uno in dettaglio.

Indici di colonna

Possiamo creare un indice per una particolare colonna usando @Index. Considera un esempio di entità Cliente come mostrato di seguito e indice definito perfirstName colonna,

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm"; 

@Entity() 
export class Student { 

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Index() 
   @Column() 
   firstName: string; 
   
   @Column() 
   lastName: string; 
   
   @Column() 
   age: number; 
   
   @Column() 
   address: string; 
}

@Index consentire di specificare il nome anche per un indice -

@Index("Name-idx") 
@Column() 
firstName: string;

Indici unici

Per specificare i vincoli Unique nella colonna, utilizza la proprietà seguente:

{ unique: true }

Ad esempio, di seguito è riportato il codice per specificare un indice univoco per la colonna Nome:

@Index({ unique: true }) 
@Column() 
firstName: string;

Per applicare indici per più di una colonna, possiamo specificarlo direttamente dopo @Entity (). Il codice di esempio è il seguente:

@Entity() 
@Index(["firstName", "lastName"]) @Index(["firstName", "lastName"], { unique: true })

Indici spaziali

L'indice spaziale consente di accedere agli oggetti spaziali. MySQL e PostgreSQL supportano gli indici spaziali. Per abilitare gli indici spaziali nella colonna, aggiungi la seguente proprietà:

{ spatial: true }

Il tipo spaziale ha più sottotipi come geometria, punto, stringa di linea, poligono ecc., Ad esempio, se si desidera aggiungere il tipo spaziale di punti nella colonna, utilizzare il codice seguente:

@Column("point") 
@Index({ spatial: true }) 
point: string;

Disabilita la sincronizzazione

Per disabilitare la sincronizzazione, utilizzare l'opzione di seguito su @Index decoratore -

{ synchronize: false }

Il listener di entità viene utilizzato nelle entità che supportano il metodo personalizzato e ascoltano eventi specifici. Possiamo definire qualsiasi metodo personalizzato di entità utilizzando i decoratori. Capiamo in breve i decoratori.

  • @AfterLoad - Quando l'entità viene caricata utilizzando QueryBuilder o repository / manager, verrà chiamato questo metodo.
  • @BeforeInsert - Questo metodo chiamerà prima che l'entità venga inserita utilizzando repository / manager.
  • @AfterInsert - Questo metodo chiamerà dopo che l'entità è stata inserita utilizzando repository / manager.
  • @BeforeUpdate - Questo metodo lo chiamerà prima che un'entità esistente venga aggiornata utilizzando repository / manager.
  • @AfterUpdate - Chiamerà dopo che un'entità è stata aggiornata.
  • @BeforeRemove - Chiamerà prima che un'entità venga rimossa.
  • @AfterRemove - Chiamerà dopo che un'entità è stata rimossa.

Abbonato

L'abbonato viene utilizzato per ascoltare eventi di entità specifiche. È implementato daEntitySubscriberInterface. Comprendiamo un semplice esempio di come utilizzare il listener di entità nell'abbonato. Considera che l'entità Studente è mostrata di seguito:

Student.ts

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm"; 

@Entity() 
export class Student {     

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   Name: string; 
   
   @Column() 
   age: number; 
}

Crea abbonato studente

L'abbonato viene creato utilizzando il comando seguente:

typeorm subscriber:create -n StudentSubscriber

Il comando precedente crea una directory del sottoscrittore all'interno del tuo progetto src. Quindi, il file StudentSubscriber.ts viene creato all'interno del tuo abbonato. Potresti vedere la seguente risposta,

Subscriber /Users/workspace/TypeORM/FirstProject/src/subscriber/StudentSubscriber.ts has been created successfully.

Ora sposta su file, potresti vedere la codifica seguente:

StudentSubscriber.ts

import {EventSubscriber, EntitySubscriberInterface} from "typeorm"; 

@EventSubscriber() 
export class StudentSubscriber implements EntitySubscriberInterface<any> { 
}

Ora aggiungi le seguenti modifiche nel file,

import {EventSubscriber, EntitySubscriberInterface,InsertEvent} from "typeorm"; 
import {Student} from "../entity/Student"; 

@EventSubscriber() 
export class StudentSubscriber implements EntitySubscriberInterface<any> { 
   listenTo() 
   { 
      return Student; 
   } 
   
   afterInsert(event: InsertEvent<Student>) { 
      console.log(event); 
   } 
}

Qui,

Abbiamo usato afterInsert()metodo per chiamare l'evento dell'entità. Allo stesso modo, puoi usare anche altri eventi. Abbiamo già configurato il file ormconfig.json. Ora aggiungi le seguenti modifiche inindex.ts file come segue -

index.ts

import "reflect-metadata"; import {createConnection} from "typeorm"; import {Student} from "./entity/Student"; 

createConnection().then(async connection => {

   console.log('connection established'); 
}).catch(error => console.log(error));

Dopo aver eseguito l'applicazione, potresti vedere l'output di seguito sullo schermo,

Registrazione

La registrazione del database è una parte importante della progettazione di una soluzione di database a disponibilità elevata perché i registri del database consentono il ripristino da un errore e consentono di sincronizzare i database primari e secondari.

A tutti i database sono associati dei registri. Questi registri conservano i record delle modifiche al database. Se un database deve essere ripristinato a un punto oltre l'ultimo backup completo, non in linea, i log sono necessari per eseguire il roll forward dei dati fino al punto di errore.

Opzioni di registrazione

La registrazione viene abilitata aggiungendo {logging: true} nella connessione al database. Le opzioni di registrazione sono classificate in diversi tipi. Sono i seguenti:

query- restituisce tutte le query di registro. È definito come indicato di seguito:

{ 
   host: "localhost",
   ... 
   logging: ["query"] 
}

error- restituisce i log per tutte le query e gli errori non riusciti. È definito di seguito:

{ 
   host: "localhost",
   ... 
   logging: ["error"] 
}

schema - restituisce i log per lo schema.

warn - restituisce avvisi ORM interni.

info - restituisce i log dei messaggi informativi interni di ORM.

log - restituisce i messaggi di registro ORM interni.

Registratore personalizzato

La registrazione personalizzata è un'opzione di registrazione semplice e altamente personalizzabile. Possiamo creare la nostra classe logger utilizzando il codice seguente:

import {Logger} from "typeorm"; 

export class MyCustomLogger implements Logger { 
   
   // implement all methods from logger class 
}

L'opzione di connessione è specificata in ormconfig.json come segue:

name: "mysql", 
type: "mysql", 
host: "localhost", 
port: 3306, 
username: "root", 
password: "root", 
database: "test", 
logger: new MyCustomLogger()

La lingua predefinita supportata da TypeORM è TypeScript. Poiché TypeScript supporta la tipizzazione statica, le classi e i decoratori, è facile definire l'entità ei suoi attributi. Allo stesso tempo,JavaScript è necessario anche in alcuni progetti in cui la lingua preferita è JavaScript. TypeORMfornisce il supporto completo anche per il linguaggio JavaScript. TypeORM supporta sia le versioni es5 che es6 di JavaScript.

In questo capitolo, impariamo come scrivere un'applicazione TypeORM in JavaScript ES5 (ECMAScript 5).

Apri un prompt dei comandi e vai al tuo spazio di lavoro.

cd /path/to/workspace/

Esegui il comando seguente per creare un progetto TypeORM.

typeorm init --name typeorm-javascript-student-app --database mysql

Aperto package.json file per rimuovere i riferimenti tipografici.

originale

{ 
   "name": "typeorm-javascript-student-app", "version": "0.0.1", 
   "description": "Awesome project developed with TypeORM.", "devDependencies": { 
      "ts-node": "3.3.0", "@types/node": "^8.0.29", "typescript": "3.3.3333" 
   }, 
   "dependencies": { 
      "typeorm": "0.2.24", "reflect-metadata": "^0.1.10", "mysql": "^2.14.1" 
   }, 
   "scripts": { 
      "start": "ts-node src/index.ts" } 
}

aggiornato

{ 
   "name": "typeorm-javascript-student-app", "version": "0.0.1", 
   "description": "Awesome project developed with TypeORM.", "dependencies": { 
      "typeorm": "0.2.24",
      "mysql": "^2.14.1" 
   }, 
   "scripts": { 
   "start": "node src/index.js" 
   } 
}

Qui,

  • Rimosso il file devDependencies sezione e pacchetto relativo al dattiloscritto in dependences sezione.
  • Modificato lo script di avvio in modo che punti il ​​codice JavaScript invece del codice dattiloscritto.

Esegui il comando seguente per installare i pacchetti necessari.

npm install

Rimuovere tsconfig.json e il file index.ts.

Rimuovi il file User.ts all'interno della cartella dell'entità e quindi crea l'entità studente in formato json, student.json come di seguito specificato -

{ 
   "name": "Student", 
   "columns": { 
      "id": { 
         "primary": true, 
         "type": "int", 
         "generated": true 
      }, 
      "name": { 
         "type": "varchar" 
      }, 
      "age": { 
         "type": "integer" 
      } 
   } 
}

Crea un nuovo file, src / index.js e inserisci il codice seguente -

var typeorm = require("typeorm"); var EntitySchema = typeorm.EntitySchema; 

typeorm.createConnection({ 
   "type": "mysql", 
   "host": "localhost", 
   "port": 3306, 
   "username": "root", 
   "password": "123456", 
   "database": "typeorm_test_db",
   "synchronize": true, 
   "logging": false, 
   entities: [ new EntitySchema(require("./entity/student.json")) 
   ] 
}) 
.then(function(connection) { 
   return connection.getRepository("Student"); }) .then(function(studentRepository) { 
   var student = { 
      name: "Student1", 
      age: 18 
   }; 
   return studentRepository.save(student) .then(function(savedStudent) { console.log("Student has been successfully saved: ", savedStudent); 
   return studentRepository.find(); }) 
   .then(function(students) { console.log("All students: ", students); 
   return; 
   }) 
   .catch(function(error) { console.log("Error: ", error); return; 
   }) 
}) 
.catch(function(error) { console.log("Error: ", error) 
   return; });

Qui,

Abbiamo utilizzato gli stessi metodi di tipoORM tranne le modifiche sotto menzionate,

  • Usato EntitySchema per configurare l'entità studente.
  • Blocchi del concetto di promessa JavaScript utilizzati (quindi / cattura / infine).

Ora, esegui l'applicazione usando il comando seguente:

npm start

L'applicazione inserisce le informazioni sullo studente nel database, quindi recupera tutto lo studente nel database e lo mostra nella console come mostrato di seguito:

> [email protected] start /path/to/workspace/typeorm-javascript-student-app

> node src/index.js 

Student has been successfully saved: { name: 'Student1', age: 18, id: 1 } All students: [ { id: 1, name: 'Student1', age: 18 } ]

Questo capitolo spiega l'ampio supporto del database MongoDB fornito da TypeORM. Si spera di aver installato mongodb utilizzando npm. Se non è installato, utilizzare il comando seguente per installare il driver MongoDB,

npm install mongodb --save

Creare un progetto

Creiamo un nuovo progetto usando MongoDB come segue:

typeorm init --name MyProject --database mongodb

Configura ormconfig.json

Configuriamo le opzioni host, porta e database di MongoDB nel file ormconfig.json come specificato di seguito -

ormconfig.json

{ 
   "type": "mongodb", 
   "host": "localhost", 
   "port": 27017, 
   "database": "test", 
   "synchronize": true, 
   "logging": false, 
   "entities": [ 
      "src/entity/**/*.ts" 
   ], 
   "migrations": [ "src/migration/**/*.ts" 
   ], 
   "subscribers": [ "src/subscriber/**/*.ts" 
   ], 
   "cli": { 
      "entitiesDir": "src/entity", "migrationsDir": "src/migration", "subscribersDir": "src/subscriber" 
   } 
}

Definisci entità e colonne

Creiamo una nuova entità chiamata Student all'interno della tua directory src. Le entità e le colonne sono le stesse. Per generare la colonna della chiave primaria, usiamo@PrimaryColumn o

@PrimaryGeneratedColumn. Questo può essere definito come @ObjectIdColumn. Di seguito è mostrato un semplice esempio:

Student.ts

import {Entity, ObjectID, ObjectIdColumn, Column} from "typeorm"; 

@Entity() 
export class Student {  

   @ObjectIdColumn() 
   id: ObjectID; 
   
   @Column() 
   Name: string; 
   
   @Column() 
   Country: string; 
}

Per salvare questa entità, apri il file index.ts e aggiungi le seguenti modifiche:

index.ts

import "reflect-metadata"; 
import {createConnection} from "typeorm"; 
import {Student} from "./entity/Student"; 

createConnection().then(async connection => { 

   console.log("Inserting a new Student into the database..."); const std = new Student(); std.Name = "Student1"; 
   std.Country = "India"; 
   await connection.manager.save(std); console.log("Saved a new user with id: " + std.id); 
   
   console.log("Loading users from the database..."); 
   const stds = await connection.manager.find(Student); console.log("Loaded users: ", stds); 
   
   console.log("TypeORM with MongoDB"); 
}).catch(error => console.log(error));

Ora avvia il tuo server e otterrai la seguente risposta:

npm start

MongoDB EntityManager

Possiamo anche usare EntityManager per recuperare i dati. Di seguito è mostrato un semplice esempio:

import {getManager} from "typeorm";

const manager = getManager(); 
const result = await manager.findOne(Student, { id:1 });

Allo stesso modo, possiamo anche utilizzare il repository per accedere ai dati.

import {getMongoRepository} from "typeorm"; 

const studentRepository = getMongoRepository(Student); 
const result = await studentRepository.findOne({ id:1 });

Se si desidera filtrare i dati utilizzando l'opzione uguale come segue:

import {getMongoRepository} from "typeorm"; 

const studentRepository = getMongoRepository(Student); 
const result = await studentRepository.find({ 
   where: { 
      Name: {$eq: "Student1"}, 
   } 
});

Come abbiamo visto in questo capitolo, TypeORM rende facile lavorare con il motore di database MongoDB.

Express è uno dei popolari framework JavaScript per creare applicazioni web. Impariamo come usareTypeORM insieme a Express Framework in questo capitolo.

Creazione di una semplice applicazione

TypeORM CLI fornisce un'opzione semplice per creare un'applicazione web rapida e funzionante completa (applicazione API Restful) integrata con TypeORM. Il comando CLI per creare l'applicazione è il seguente:

cd /path/to/workspace typeorm init --express --name typeorm-express-sample --database mysql

Il comando sopra creerà una nuova applicazione web nella cartella typeorm-express-sample. La struttura dell'applicazione è la seguente:

│ .gitignore 
│ ormconfig.json 
│ package.json 
│ README.md 
│ tsconfig.json 
│ └───src 
      │ index.ts 
      │ routes.ts 
      │ 
      ├───controller 
      │      UserController.ts 
      │ 
      ├───entity 
      │      User.ts 
      │ 
      └───migration

Qui,

Come sappiamo, ormconfig.json è il TypeORMfile di configurazione. Il codice è il seguente,

{ 
   "type": "mysql", 
   "host": "localhost", 
   "port": 3306, 
   "username": "test", 
   "password": "test", 
   "database": "test", 
   "synchronize": true, 
   "logging": false, 
   "entities": [
      "src/entity/**/*.ts" 
   ], 
   "migrations": [ "src/migration/**/*.ts" 
   ], 
   "subscribers": [ "src/subscriber/**/*.ts" 
   ], 
   "cli": { 
      "entitiesDir": "src/entity", "migrationsDir": "src/migration", "subscribersDir": "src/subscriber" 
   } 
}

Qui, modifica l'impostazione del database in modo che corrisponda all'impostazione del database locale.

package.json file è la configurazione principale dell'applicazione.

tsconfig.json file contiene la configurazione relativa a TypeScript.

entity la cartella contiene il file TypeORMModelli. Un modello utente predefinito verrà creato dalla CLI ed è il seguente:

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm"; 

@Entity() 
export class User { 
   
   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   firstName: string; 
   
   @Column() 
   lastName: string; 
   
   @Column() 
   age: number; 
}

controllercartella contiene i controller express. CLI crea un controller API utente predefinito con aggiungi / elenca / elimina i dettagli dell'utente. Il codice è il seguente:

import {getRepository} from "typeorm"; import {NextFunction, Request, Response} from "express"; import {User} from "../entity/User"; 

export class UserController {

   private userRepository = getRepository(User); 
   
   async all(request: Request, response: Response, next: NextFunction) { 
      return this.userRepository.find(); 
   } 
   
   async one(request: Request, response: Response, next: NextFunction) { 
      return this.userRepository.findOne(request.params.id); 
   } 
   
   async save(request: Request, response: Response, next: NextFunction) { 
      return this.userRepository.save(request.body); 
   } 
   
   async remove(request: Request, response: Response, next: NextFunction) { 
      let userToRemove = await this.userRepository.findOne(request.params.id); 
      await this.userRepository.remove(userToRemove); 
   } 
}

Qui,

all viene utilizzato per recuperare tutti gli utenti dal database.

one metodo viene utilizzato per recuperare un singolo utente dal database utilizzando user id

save viene utilizzato per salvare le informazioni dell'utente nel database.

delete metodo viene utilizzato per eliminare l'utente dal database utilizzando user id

routes.ts file mappa i metodi del controller utente all'URL corretto e il codice è il seguente:

import {UserController} from "./controller/UserController"; 

export const Routes = [{ 
      method: "get", 
      route: "/users", 
      controller: UserController, action: "all" 
   }, { 
      method: "get", 
      route: "/users/:id", controller: UserController, action: "one" 
   }, { 
      method: "post", 
      route: "/users", 
      controller: UserController, action: "save" 
   }, { 
      method: "delete", route: "/users/:id", controller: UserController,
      action: "remove" 
}];

Qui,

/ users url è mappato al controller utente. Ogni verbo post, get e delete viene mappato su metodi diversi.

Finalmente, index.tsè il nostro punto di ingresso principale dell'applicazione web. Il codice sorgente è il seguente:

import "reflect-metadata"; 
import {createConnection} from "typeorm"; 
import * as express from "express"; import * as bodyParser from "body-parser"; 
import {Request, Response} from "express"; 
import {Routes} from "./routes"; import {User} from "./entity/User"; 

createConnection().then(async connection => { 

   // create express app const app = express(); app.use(bodyParser.json()); 

   // register express routes from defined application routes Routes.forEach(route => { 
      (app as any)[route.method](route.route, (req:   Request, res: Response, next: Function) => { 
         const result = (new (route.controller as any))[route.action](req, res, next); 
         if (result instanceof Promise) { 
            result.then(result => result !== null && result !== undefined ? res.send(result) : undefined); 
         } else if (result !== null && result !== undefined) { 
            .json(result); 
         } 
      }); 
   }); 
      
   // setup express app here 
   // ... 
      
   // start express server app.listen(3000); 
      
   // insert new users for test await connection.manager.save(connection.manager.create(User, { 
      firstName: "Timber",
      lastName: "Saw", 
      age: 27 
   }));
   await connection.manager.save(connection.manager.create(User, { 
      firstName: "Phantom", 
      lastName: "Assassin", 
      age: 24 
   })); 
      
   console.log("Express server has started on port 3000. Open http://localhost:3000/users to see results"); 
}).catch(error => console.log(error));

Qui, l'applicazione configura le rotte, inserisce due utenti e quindi avvia l'applicazione web sulla porta 3000 . Possiamo accedere all'applicazione all'indirizzohttp://localhost:3000

Per eseguire l'applicazione, segui i passaggi seguenti:

Cerchiamo di installare i pacchetti necessari utilizzando il comando seguente:

npm install

Produzione

npm notice created a lockfile as package-lock.json. You should commit this file. 
npm WARN [email protected] No repository field. 
npm WARN [email protected] No license field. 

added 176 packages from 472 contributors and audited 351 packages in 11.965s 

3 packages are looking for funding  run `npm fund` for details 

found 0 vulnerabilities

Esegui il comando seguente per avviare l'applicazione.

npm start

Produzione

> [email protected] start /path/to/workspace/typeorm-express-sample 
> ts-node src/index.ts 

Express server has started on port 3000. Open http://localhost:3000/users to see results

Accediamo alla nostra API dell'applicazione Web utilizzando il comando curl come di seguito:

curl http://localhost:3000/users

Qui,

curl è un'applicazione a riga di comando per accedere all'applicazione web dal prompt dei comandi. Supporta tutti i verbi HTTP come get, post, delete, ecc.,

Produzione

[{"id":1,"firstName":"Timber","lastName":"Saw","age":27},{"id":2,"firstName":"Phantom","lastName":"Assassin","age":24}]

Per recuperare il primo record, possiamo usare il comando seguente:

curl http://localhost:3000/users/1

Produzione

{"id":1,"firstName":"Timber","lastName":"Saw","age":27}

Per eliminare un record utente, possiamo usare il comando seguente:

curl -X DELETE http://localhost:3000/users/1

Come abbiamo visto in questo capitolo, TypeORM può essere facilmente integrato in un'applicazione rapida.

Le migrazioni sono come il controllo della versione per il tuo database. Viene utilizzato per modificare e condividere lo schema del database dell'applicazione. Questa sezione spiega come funzionano le migrazioni in TypeORM.

Creazione di una nuova migrazione

Per creare una nuova migrazione, prima dobbiamo impostare la connessione in ormconfig.json. È definito di seguito:

ormconfig.json

"type": "mysql", 
"host": "localhost", 
"port": 8889, 
"username": "root", 
"password": "root", 
"database": "Library", 
"entities": ["entity/*.js"], "migrationsTableName": "student_migration_table", "migrations": ["migration/*.js"], "cli": { 
   "migrationsDir": "migration" 
}

Qui,

  • migrationsTableName - fa riferimento al nome della tabella di migrazione.
  • migrations - TypeORM carica le migrazioni dalla directory data.
  • cli - indica che la migrazione verrà creata all'interno della directory specifica.

Crea entità Libro

Creiamo un'entità denominata Book entità all'interno src/entity/Book.ts come segue -

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; 
@Entity() 
export class Book { 

   @PrimaryGeneratedColumn() 
   id: number; 
   
   @Column() 
   title: string;
   
   @Column() 
   text: string; 
}

Esegui CLI per creare una nuova migrazione

Ora possiamo eseguire una nuova migrazione utilizzando la CLI come segue:

Sintassi

typeorm migration:create -n <migration-name>

Esempio

typeorm migration:create -n myMigration

Dopo aver eseguito il comando precedente, potresti vedere la risposta di seguito:

Migration /path/to/project/src/migration/1587101104904-myMigration.ts has been generated successfully.

Ora, spostati dentro src/migration/1587101104904-myMigration.ts il file è simile a questo.

import {MigrationInterface, QueryRunner} from "typeorm"; 

export class myMigration1587101104904 implements MigrationInterface {      

   public async up(queryRunner: QueryRunner): Promise<any> { 
   } 
   
   public async down(queryRunner: QueryRunner): Promise<any> { 
   } 
}

Qui,

Abbiamo due metodi up e down. up viene utilizzato per aggiungere modifiche alla migrazione e down viene utilizzato per annullare le modifiche nella migrazione.

Aggiungiamo up metodo all'interno myMigration.ts file come specificato di seguito -

import {MigrationInterface, QueryRunner} from "typeorm"; 

export class Book1587131893261 implements MigrationInterface { 

   public async up(queryRunner: QueryRunner): Promise<any> { 
      await queryRunner.query(`ALTER TABLE book ADD COLUMN price int`); 
   }
   public async down(queryRunner: QueryRunner): Promise<any> { } 
}

Qui,

Abbiamo aggiunto una nuova colonna price dentro booktavolo. Ora, esegui la CLI per aggiungere le modifiche di cui sopra.

ts-node ./node_modules/typeorm/cli.js migration:run

Il comando precedente esegue le migrazioni e le esegue in sequenza. Ora puoi vedere le seguenti modifiche sullo schermo:

Produzione

Ora apri il tuo server mysql, viene aggiunta una nuova colonna. È mostrato di seguito -

Allo stesso modo, possiamo modificare il tipo di dati del titolo della colonna in varchar (30) come segue,

import {MigrationInterface, QueryRunner} from "typeorm"; 

export class Book1587131893261 implements MigrationInterface { 

   public async up(queryRunner: QueryRunner): Promise<any> { 
   await queryRunner.query(`ALTER TABLE book MODIFY COLUMN title varchar(30)`); 
      } 
   public async down(queryRunner: QueryRunner): Promise<any> { 
   } 
}

Ora, esegui lo stesso comando e potresti le seguenti modifiche:

ts-node ./node_modules/typeorm/cli.js migration:run

Produzione

Book la tabella viene modificata come,

Ripristina la migrazione

Aggiungiamo il codice seguente all'interno down metodo per annullare la migrazione -

import {MigrationInterface, QueryRunner} from "typeorm"; 

export class Book1587131893261 implements MigrationInterface { 
   
   public async up(queryRunner: QueryRunner): Promise<any> { 
   
   } 
   public async down(queryRunner: QueryRunner): Promise<any> { 
   
      await queryRunner.query(`ALTER TABLE book drop column price`); // reverts things made in "up" method
   } 
}

Ora, esegui il comando seguente per annullare tutte le modifiche:

ts-node ./node_modules/typeorm/cli.js migration:revert

Potresti vedere la seguente risposta:

Produzione

Book la tabella viene modificata come,

Produzione

Come abbiamo visto in questo capitolo, TypeORM semplifica la scrittura di script di migrazione del database.

Questa sezione spiega in dettaglio i comandi CLI TypeORM.

Crea il progetto TypeORM

typeorm initè il modo più semplice e veloce per impostare un progetto TypeORM. Puoi creare un nuovo progetto come,

typeorm init --name Demoproject --database mysql

Dopo aver eseguito il comando, sullo schermo verrà visualizzato il seguente output:

Project created inside /Users/workspace/TypeORM/Demoproject directory.

Crea un'entità

Per creare una nuova entità utilizzando CLI come,

typeorm entity:create -n Person

Ora, l'entità Persona viene creata all'interno della directory src del progetto.

Entity /Users/workspace/TypeORM/Demoproject/src/entity/Person.ts has been created successfully.

Se hai una struttura di progetto multimodulo con più entità in directory diverse, puoi utilizzare il comando seguente,

typeorm entity:create -n Person -d src/Person/entity

Crea un nuovo iscritto

Per creare un nuovo abbonato utilizzando la CLI come segue:

typeorm subscriber:create -n PersonSubscriber

Potresti vedere la seguente risposta:

Subscriber /path/to/TypeORM/Demoproject/src/subscriber/PersonSubscriber.ts has been created successfully.

Crea migrazioni

È possibile creare una nuova migrazione utilizzando la CLI come indicato di seguito:

typeorm migration:create -n PersonMigration

Il comando precedente ha creato una directory di migrazione all'interno del tuo progetto src. I file di migrazione sono archiviati al suo interno.

Migration /path/to/TypeORM/Demoproject/src/migration/1587395030750-PersonMigration.ts has been generated successfully.

Schema del database

Per sincronizzare uno schema di database, utilizzare il comando seguente:

typeorm schema:sync

Per eliminare completamente uno schema di database, utilizzare il comando seguente:

typeorm schema:drop

Query SQL

Se vuoi eseguire qualsiasi query sql, possiamo eseguirla direttamente da qui. Ad esempio, per visualizzare tutti i record dei clienti, utilizzare la query seguente:

typeorm query "select * from customers"

Se vuoi cancellare tutto ciò che è memorizzato nella cache. Puoi farlo usando il seguente comando:

typeorm cache:clear

Conclusione

TypeORM è un eccellente framework ORM open source per creare applicazioni scalabili e di alta qualità da applicazioni su piccola scala ad applicazioni aziendali su larga scala con più database.