TypeORM - Guía rápida

El marco TypeORM es un Object Relational Mapping (ORM)marco de referencia. En general,Object parte se refiere al dominio / modelo en su aplicación, Relational parte se refiere a la relación entre las tablas en el sistema de gestión de bases de datos relacionales (por ejemplo, Oracle, MySQL, MS-SQL, PostgreSQL, etc.) y finalmente el Mapping parte se refiere al acto de unir el modelo y nuestras tablas.

ORM es un tipo de herramienta que mapea entidades con tablas de base de datos. ORM proporciona un proceso de desarrollo simplificado mediante la automatización de la conversión de objeto a tabla y de tabla a objeto. Una vez que pueda escribir su modelo de datos en un solo lugar, será más fácil actualizar, mantener y reutilizar el código.

Dado que el modelo está débilmente vinculado al resto de la aplicación, puede cambiarlo sin ninguna dependencia estricta con otra parte de la aplicación y puede usarlo fácilmente en cualquier lugar dentro de la aplicación. TypeORM es muy flexible, abstrae el sistema DB de la aplicación y nos permite beneficiarnos del uso del concepto OOPS.

Visión general

TypeORM es una biblioteca Object Relational Mapper que se ejecuta en node.js y está escrita en TypeScript. TypeScript es una mejora de JavaScript con escritura opcional. TypeScript es un lenguaje compilado. No se interpreta en tiempo de ejecución. El compilador TypeScript toma archivos TypeScript (.ts) y los compila en archivos JavaScript (.js).

TypeORM admite múltiples bases de datos como MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana y WebSQL. TypeORM es un ORM fácil de usar para crear nuevas aplicaciones que se conectan a bases de datos. La funcionalidad TypeORM son conceptos específicos de RDBMS.

Podemos crear rápidamente nuevos proyectos y microservicios. Está inspirado en herramientas similares como Hibernate, Doctrine, Entity framework, etc., de otros lenguajes de programación.

Características de TypeORM

TypeORM viene con las siguientes características:

  • Cree automáticamente esquemas de tablas de base de datos basados ​​en sus modelos.
  • Inserte, actualice y elimine fácilmente objetos en la base de datos.
  • Cree mapeo (uno a uno, uno a muchos y muchos a muchos) entre tablas.
  • Proporciona comandos CLI simples.

Beneficios de TypeORM

TypeORM es un marco ORM fácil de usar con codificación simple. Tiene los siguientes beneficios:

  • Aplicaciones de alta calidad y poco acopladas.
  • Aplicaciones escalables.
  • Integre fácilmente con otros módulos.
  • Se adapta perfectamente a cualquier arquitectura, desde aplicaciones pequeñas hasta aplicaciones empresariales.

Este capítulo explica cómo instalar TypeORM en su máquina. Antes de pasar a la instalación, asegúrese de que npm esté instalado. Para confirmar que tiene npm, puede ejecutar el siguiente comando en su terminal.

npm -v

Muestra la versión. Si no está instalado, descargue la última versión e instálela en su máquina.

Instalar TypeORM

Instalemos TypeORM localmente usando el módulo npm -

npm install typeorm --save

Después de ejecutar el comando anterior, obtendrá una respuesta como se indica a continuación:

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

Alternativamente, para instalar TypeORM globalmente, use el siguiente comando:

npm install typeorm -g

Después de eso, instale el paquete opcional reflect-metadata usando npm -

npm install reflect-metadata --save

Podrías ver la siguiente respuesta:

+ [email protected] 

added 1 package and audited 1236 packages in 2.426s

Ahora, instale otro paquete opcional. mecanografía de nodos usando el siguiente comando:

npm install @types/node --save

Podrías ver la siguiente respuesta:

+ @types/[email protected] 

added 1 package and audited 1236 packages in 2.167s

Instalar el controlador de la base de datos

En esta sección, instalemos los paquetes de nodos necesarios para nuestra base de datos.

Instalar MySQL o MariaDB paquete, use el siguiente comando:

npm install mysql --save

Podrías ver la siguiente respuesta:

+ [email protected] 

added 1 package and audited 1236 packages in 4.36s

Instalar PostgreSQL paquete, use el siguiente comando:

npm install pg --save

Podrías ver la siguiente respuesta:

+ [email protected] 

added 1 package and audited 1236 packages in 2.863s

Instalar SQLite paquete, use el siguiente comando:

npm install sqlite3 --save

Podrías ver la siguiente respuesta:

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

Instalar Microsoft SQL Server paquete, use el siguiente comando:

npm install mssql --save

Tu pantalla se parece a esto,

+ [email protected] 

added 1 package and audited 1655 packages in 2.378s

Instalar sql.js paquete, use el siguiente comando:

npm install sql.js --save

Podrías ver la siguiente respuesta:

+ [email protected] 

added 1 package and audited 1655 packages in 6.462s

Instalar Oracle server paquete, use el siguiente comando:

npm install oracledb --save

Podrías ver la siguiente respuesta:

+ [email protected] 

added 1 package and audited 1655 packages in 2.265s

Instalar mongodb paquete, use el siguiente comando:

npm install mongodb --save

Podrías ver la siguiente respuesta:

+ [email protected] 

added 1 package and audited 1655 packages in 3.716s

Este capítulo explica cómo crear una aplicación TypeORM simple. Creemos un nuevo directorio llamado 'TypeORM' y vayamos al directorio.

cd /path/to/TypeORM/

Sintaxis

Utilice el siguiente comando para crear un nuevo proyecto:

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

Ejemplo

typeorm init --name FirstProject --database mysql

Aquí,

FirstProject es el nombre de su proyecto y sqlite3es el nombre de la base de datos. Después de ejecutar el comando anterior, podría ver la siguiente respuesta,

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

Ahora, muévase a nuestro directorio de proyectos e instale las dependencias del proyecto usando npm módulo,

$ cd FirstProject $ npm install

Estructura del proyecto

Entendamos la estructura del proyecto de nuestro proyecto recién creado, FirstProject.

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

Aquí,

  • src - contiene el código fuente de su aplicación en TypeScriptidioma. Tiene un archivoindex.ts y dos subdirectorios entity y migration.
  • index.ts - Su punto de entrada a la aplicación.
  • entity - Contiene modelos de base de datos.
  • migration - contiene el código de migración de la base de datos.
  • node_modules - módulos npm guardados localmente.
  • ormconfig.json- Archivo de configuración principal de su aplicación. Contiene detalles de configuración de la base de datos y configuración de entidades.
  • package.json - Contiene dependencias de módulo de nodo.
  • package-lock.json - Archivo generado automáticamente y relacionado con package.json.
  • tsconfig.json - Contiene opciones de compilador específicas de TypeScript.

archivo ormconfig.json

Comprobemos la opción de configuración disponible para nuestra aplicación. Abra el archivo ormconfig.json y se verá similar a esto:

{ 
   "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
   }    
 }

Aquí,

type, host, username, password, database y las opciones de puerto están relacionadas con la configuración de la base de datos. mysql se puede configurar usando la siguiente configuración:

{ 
   "type": "mysql", 
   "host": "localhost", 
   "port": 3306, 
   "username": "db_username", "password": "db_password", "database": "db_name" 
}
  • entities - hace referencia a la ubicación de sus clases de entidad.
  • migrations - hace referencia a la ubicación de sus clases de migración.
  • subscribers - se refiere a la ubicación de sus clases de abonado.
  • cli - se refiere a la opción utilizada por TypeORM CLI para generar automáticamente el código

Inicie el servidor MySql

Antes de iniciar la aplicación, inicie su MySQL servidor o cualquier servidor de base de datos utilizado por usted y asegúrese de que esté funcionando correctamente.

Ejecutar aplicación

Una vez que todo está configurado, podemos ejecutar la aplicación usando el siguiente comando:

npm start

Podrías ver la siguiente respuesta:

> [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.

La aplicación insertó un nuevo usuario en la base de datos y luego lo cargó de forma inversa desde la base de datos y finalmente mostró el usuario cargado en la consola. Hemos creado con éxito un nuevoTypeORM aplicación, configúrelo y ejecute la aplicación.

Discutiremos sobre cómo se ejecutan los datos detalladamente en los próximos capítulos.

Para interactuar con la base de datos, necesitamos un objeto de conexión a la base de datos. Necesitamos crear un objeto de conexión antes de realizar la operación de la base de datos y tenemos que terminarlo una vez que se realizan las operaciones de la base de datos. Aprendamos sobre la API de conexión proporcionada por TypeORM en esta sección.

Creando una nueva conexión

Antes de crear una nueva conexión, debemos configurar los detalles de la conexión de la base de datos en el ormconfig.jsonarchivo de configuración. A continuación se muestra un ejemplo de detalles de conexión:

ormconfig.json

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

Aquí,

  • name - Nombre de la conexión a la base de datos.
  • type - Tipo de base de datos.
  • host - Nombre de host del servidor de la base de datos.
  • port - Puerto del servidor de la base de datos.
  • username - Nombre de la cuenta que tiene acceso a la base de datos.
  • password - Contraseña de la cuenta mencionada anteriormente.
  • database - Nombre de la base de datos a conectar.

createConnection

CreateConnectionTypeORM proporciona el método para crear una nueva conexión. Se define a continuación,

import { createConnection, Connection } from "typeorm"; 

const connection = await createConnection({ 

});

Aquí, createConnection utilizará los detalles de configuración especificados en el archivo ormconfig.json.

Alternativamente, puede definir la URL de conexión como argumentos para el método createConnection como se especifica a continuación:

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

Aquí,

createConnection devuelve un objeto, que se puede utilizar para abrir / cerrar la conexión a la base de datos.

Varias conexiones

TypeORM también ofrece una opción para crear múltiples conexiones a bases de datos. Primero, el archivo de configuración ormconfig.json se puede utilizar para especificar los detalles de la conexión de múltiples bases de datos. Configuremos múltiples bases de datos en ormconfig.json como se especifica a continuación,

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

Ahora, podemos usar el argumento proporcionado por el método createConnection para especificar el nombre de la conexión para crear el objeto de conexión como se menciona a continuación:

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

Aquí,

createConnection utilizará los detalles de configuración del firstconnection especificado en el ormconfig.json archivo para crear el objeto de conexión.

TypeORM también proporciona otra API, createConnections para crear múltiples conexiones como una vez y luego, úsela siempre que sea necesario como se especifica a continuación:

import { createConnections, Connection } from "typeorm"; 

const connections: Connection[] = await createConnections([ 

]);

Aquí,

connections mantenga todos los objetos de conexión como una matriz.

ConnectionManager

TypeORM también proporciona otra API, connectionManager para crear conexión. Se define a continuación:

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

const connectionManager = getConnectionManager(); 

const connection = connectionManager.create({ 

}); 
await connection.connect();

TypeORM prefiere el uso de createConnection encima ConnectionManager para crear objetos de conexión.

Una entidad es una colección de campos y operaciones de base de datos asociadas. Se utiliza para mapear la tabla de la base de datos y sus campos con las entidades y sus atributos. Este capítulo explica en detalle las entidades TypeORM.

Introducción

Creemos una clase Entity simple en nuestro código. Vaya a la ubicación raíz de su proyecto y vaya a la carpeta src y muévase a la carpeta de la entidad. Ahora, cree un archivo de TypeScript, Student.ts e ingrese el siguiente código:

Student.ts

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

@Entity() 
export class Student {   

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

Aquí,

  • Entity() La clase decorador se utiliza para representar que el Student la clase es una entidad.
  • PrimaryGeneratedColumn() La clase de decorador se usa para representar que la columna de identificación es la columna de clave primaria de la Student entidad.
  • Column() La clase de decorador se utiliza para representar otras columnas como Name y Age del Student entidad.

Ahora, clase de entidad Studentes creado. TypeORM generará automáticamente una tabla correspondiente a laStudent entidad en nuestra base de datos y será nombrada como student. Ahora, muévete asrc/index.ts archivo y agregue el siguiente código -

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

Aquí,

  • La línea 1-3 importa las clases relevantes, createConnection y Student
  • La línea 5 crea una nueva conexión a la base de datos usando createConnection y si se establece la conexión, ejecuta el código dentro del then bloquear.
  • La línea 10 crea un nuevo objeto Student, stud.
  • La línea 13-14 establece los atributos de nuestro objeto de montante recién creado.
  • La línea 17 guarda la entidad en la base de datos usando el método de guardar disponible en connection.manager objeto.
  • La línea 23 obtiene los detalles del estudiante de la base de datos utilizando el método de búsqueda disponible en connection.manager objeto.

Inicie el servidor Mysql y ejecute su aplicación

Hemos creado la entidad Student y creamos conexión en index.ts. Iniciemos tanto el servidor MySql como su aplicación.

npm start

Esto devolverá la siguiente salida en su pantalla:

Salida

Abierto mysql servidor siguiendo student La tabla se agrega dentro de su base de datos.

Columnas

Como se aprendió anteriormente, Entity es en realidad una colección de atributos. Como objeto de entidad se refiere a la tabla de la base de datos. Sus atributos / variables miembro hacen referencia a los campos / columnas de la tabla de la base de datos correspondiente. TypeORM admite todo tipo de campos de base de datos a través de la clase Column. Aprendamos los diferentes tipos de columna admitidos por TypeORM en este capítulo.

@Column() La clase decorador se usa para representar la columna y su tipo en la entidad.

Por ejemplo, el atributo de edad de la entidad de estudiante y el tipo de atributo de edad se pueden definir de la siguiente manera:

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

Aquí,

  • agees el atributo de la entidad. En otras palabras, la edad es un campo / columna en la tabla de estudiantes en la base de datos.
  • int representan el tipo de columna de edad en la base de datos.

TypeORM admite casi todos los tipos disponibles en el popular motor de base de datos. En realidad, TypeORM habilita diferentes conjuntos de tipos para cada motor de base de datos. Podemos utilizar cualquier tipo de base de datos compatible con nuestro motor de base de datos sin ningún problema.

Por ejemplo, el tipo admitido por TypeORM para el motor de base de datos postgresql es el siguiente:

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

De manera similar, TypeORM admite un conjunto diferente de tipos de datos para MySQL.

Opciones de columna

TypeORM proporciona un amplio conjunto de opciones distintas del tipo para describir la columna. Por ejemplo, la opción de longitud se refiere a la longitud del campo de la base de datos y se puede especificar de la siguiente manera:

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

Algunas de las opciones de columna más comunes son las siguientes:

  • name - Nombre del campo / columna de la base de datos.
  • length - Longitud del campo / columna de la base de datos.
  • nullable - Especifique si el campo / columna de la base de datos permite nulos o no.
  • default - Valor predeterminado del campo / columna de la base de datos.
  • primary - Especifique si el campo / columna de la base de datos es la clave principal de la tabla.
  • unique - Especifique si el campo / columna de la base de datos es único
  • *precision** - Precisión del campo / columna de la base de datos
  • scale - Escala del campo / columna de la base de datos
  • comment - Comentario o descripción del campo / columna de la base de datos

@Generado decorador

TypeORM proporciona un decorador adicional, @Generated para generar automáticamente los valores de columna. Por ejemplo, el Identificador único universal (UUID) es bastante común de usar en la base de datos para almacenar un valor único en una columna. El código de muestra para generar UUID es el siguiente:

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

Aquí,

uuid se genera automáticamente y se almacena dentro de la base de datos.

Columnas primarias

Al menos un campo de columna principal es obligatorio para cualquier entidad en la base de datos. Se clasifica en diferentes tipos de decoradores. Lo discutiremos uno por uno.

@PrimaryColumn()

El decorador @PrimaryColumn () se utiliza para crear una columna principal para cualquier tipo de datos. A continuación se muestra un ejemplo simple,

import {Entity, PrimaryColumn} from "typeorm"; 

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

Aquí,

id es un número entero, que no acepta valores duplicados, pero necesitamos asignar valores.

También podemos asignar una columna principal para uno o más campos, si la situación lo requiere.

Ejemplo

import {Entity, PrimaryColumn} from "typeorm"; 

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

@PrimaryGeneratedColumn ()

@PrimaryGeneratedColumn()El campo se usa para especificar la columna principal, así como para generar automáticamente el valor de la columna en la base de datos. Se muestra a continuación:

import {Entity, PrimaryGeneratedColumn} from "typeorm"; 

@Entity() 
export class Student {

   @PrimaryGeneratedColumn() 
   id: number;
}

Aquí,

No tiene que asignar un valor de identificación; será generado automáticamente por TypeORM en la tabla de la base de datos.

@PrimaryGeneratedColumn ("uuid")

@PrimaryGeneratedColumn también acepta un argumento para especificar el tipo de generador. Uno de los usos principales es generar una identificación única basada en UUID.

import {Entity, PrimaryGeneratedColumn} from "typeorm";

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

tipo de columna de matriz simple

La base de datos relacional avanzada admite el tipo de datos de matriz. Para admitir el tipo de datos de matriz, TypeORM proporciona un tipo de columna especial, * matriz simple "para almacenar valores de matriz primitivos. Un código de muestra para usarlo es el siguiente:

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

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

tipo de columna simple-json

Gran cantidad de motor de base de datos moderno es compatible con la base de datos JSON. Para usar el tipo de datos JSON, TypeORM proporciona un tipo especial, single-json. El código de muestra para usarlo es el siguiente:

@Entity() 
export class Student { 

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

Este valor se puede definir en index.ts como,

index.ts

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

Columnas especiales

TypeORM admite las siguientes columnas especiales

  • @CreateDateColumn - Es una columna especial para configurar la fecha de inserción de la entidad automáticamente.
  • @UpdateDateColumn - Se utiliza para configurar el tiempo de actualización de la entidad de forma automática.
  • @VersionColumn - Establecer el número de versión de la entidad automáticamente.

Herencia de la entidad

La herencia de entidades se utiliza para reducir la duplicación de entidades. Considere las siguientes entidades:

Result.ts

@Entity() 
export class Result {    

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

Grade.ts

El código de grade.ts es el siguiente:

@Entity() 
export class Grade {

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

Aquí,

Las dos entidades anteriores tienen columnas id, título y descripción. Utilizando la herencia de entidades, creamos una clase base Detalles y combinamos las dos entidades anteriores como se especifica a continuación.

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

Ahora inicie su servidor, podría ver la siguiente respuesta,

Ahora abra su servidor mysql y muévase a su base de datos, podría ver las siguientes tablas,

Tabla de calificaciones

Tabla de resultados

Las relaciones se utilizan para referirse a la relación entre la tabla en la base de datos. En general, existe una relación entre dos tablas cuando una de ellas tiene una clave externa que hace referencia a la clave principal de la otra tabla. Esta característica hace que la base de datos relacional sea más poderosa y almacene información de manera eficiente.

TypeORM permite relacionar las entidades entre sí y posteriormente tablas de base de datos. En general, la relación se puede clasificar en cuatro categorías más amplias. Son los siguientes,

one-to-one- Un objeto de la entidad dada se relaciona con un solo objeto de la entidad objetivo y viceversa. Por ejemplo, un país tendrá solo una ciudad capital y, de manera similar, una ciudad será la capital de un solo país.

many-to-one- El objeto múltiple de la entidad dada se relaciona con un objeto de la entidad objetivo. Por ejemplo, la ciudad se incluye en un solo país, pero el país puede tener varias ciudades.

one-to-many - Igual que muchos a uno, excepto que la relación se invierte.

many-to-many- El objeto múltiple de la entidad dada se relaciona con el objeto múltiple de la entidad objetivo. Por ejemplo, un artículo puede estar etiquetado en varios temas como lenguaje de programación, finanzas, etc. y, al mismo tiempo, una etiqueta en particular también puede tener varios artículos.

TypeORM también ofrece opciones para mejorar la relación de las entidades. Son los siguientes:

  • eager - El objeto de entidad de origen también carga los objetos de entidad de destino.
  • cascade - El objeto de la entidad de destino se inserta o actualiza mientras se inserta o actualiza el objeto de la entidad de origen.
  • onDelete - Los objetos de la entidad de destino también se eliminan mientras se elimina el objeto de la entidad de origen.
  • primary - Se usa para especificar que la columna de relación es clave primaria o no.
  • nullable - Se usa para especificar que la columna de relación es anulable o no.

Repasemos en detalle diferentes tipos de mapeo de relaciones.

Doce y cincuenta y nueve de la noche

Como aprendimos anteriormente, se refiere a la instancia de un campo de tabla que contiene la instancia de otro campo de tabla y viceversa. Creemos unDetails mesa -

Detalles.ts

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

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

Creemos otra entidad Cliente de la siguiente manera:

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

Aquí,

Hemos agregado mapeo OneToOne a Details mesa. @JoinColumn() contener un "id de relación" y una clave externa para Customermesa. Podemos guardar la relación enindex.ts como sigue -

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 varios y varios a uno

Como aprendimos anteriormente, se refiere a la instancia del primer campo de la tabla que contiene las múltiples instancias del segundo campo de la tabla llamado One-to-Many mapeo y múltiples instancias de la primera tabla contiene solo una instancia de la segunda tabla llamada Many-to-One cartografía.

Considere un ejemplo de Student y project entidades, mientras que el estudiante puede trabajar en más de un proyecto, pero cada proyecto es manejado por un solo estudiante.

Vamos a crear un Project entidad de la siguiente manera:

Proyecto

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

Ahora creamos Student entidad como a continuación -

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

Aquí,

@OneToMany propiedad asignada Project y @ManyToOne propiedad asignada a Student. Sin embargo,@OneToMany no puede existir sin @ManyToOne y @ManyToOne la propiedad contiene "id de relación" y clave externa.

Podemos guardar la conexión en index.ts como sigue -

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

Muchos a muchos

Como aprendimos anteriormente, se refiere a varios registros en una tabla que están relacionados con varios registros en otra tabla. Considere un ejemplo, un estudiante universitario puede inscribirse en varias clases a la vez, lo que significa que el estudiante puede tener cuatro o cinco clases por semestre y una clase puede tener muchos estudiantes.

Podemos simplemente concluir, un estudiante tiene muchas clases y una clase tiene muchos estudiantes. Creemos una entidad paraClasses como sigue -

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

@Entity() 
export class Classes { 

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

Ahora creamos Student entidad como a continuación -

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

El repositorio es específico de una entidad. En otras palabras, cada entidad tendrá su propio repositorio integrado y se puede acceder a él mediante el método getRepository () del objeto de conexión como se especifica a continuación:

const studRepository = manager.getRepository(Student);

Una vez que se crea el objeto del repositorio del estudiante, se puede usar para realizar todas las operaciones de la base de datos del objeto del estudiante.

Tipos de repositorio

Repositoryse clasifica en cuatro categorías. Son los siguientes:

Repositorio

Repositorio predeterminado de una entidad y se puede acceder usando getRepository() método como se especifica a continuación -

const studRepository = manager.getRepository(Student);

Ahora, studRepository se puede utilizar para consultar la tabla de estudiantes

TreeRepository

Se utiliza para entidades de estructura en forma de árbol y se puede acceder mediante getTreeRepository() método como se especifica a continuación -

const studcaRepository = manager.getTreeRepository(Student);

MongoRepository

Se usa dentro de las entidades de operación mongoDB y se puede acceder a él usando getMongoRepository() método como se especifica a continuación -

const detailsRepository = manager.getMongoRepository(Details);

CustomRepository

Se utiliza para personalizar el repositorio y se puede acceder a él mediante getCustomRepository() método como se especifica a continuación,

const myUserRepository = manager.getCustomRepository(UserRepository);

API de repositorio

Aprendamos el método más importante de EntityManager en este capítulo.

gerente

Podemos acceder EntityManager usando el método de administrador como se especifica a continuación -

const manager = repository.manager;

queryRunner

queryRunnerEl método devuelve un objeto de ejecución de consultas personalizado y el repositorio lo utiliza para operaciones de base de datos. El código de muestra es el siguiente:

const queryRunner = repository.queryRunner;

metadatos

metadatadevuelve los metadatos del repositorio. El código de muestra es el siguiente:

const metadata = repository.metadata;

consulta

queryEl método ejecuta consultas SQL. Consulta de selección simple como se muestra a continuación:

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

insertar

insertEl método se utiliza para insertar una nueva entidad o matriz de entidades en la base de datos. El código de muestra es el siguiente:

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

La consulta anterior es equivalente a,

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

actualizar

update se utiliza para actualizar los registros existentes en la base de datos.

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

Esta consulta funciona de manera similar a la que se menciona a continuación:

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

Eliminar

delete El método eliminará el registro especificado de la tabla,

await repository.delete(Student, 1);

Esto eliminará al estudiante con identificación 1 desde el studentmesa. Es equivalente a,

delete from student where id=1;

Si desea eliminar por nombre, utilice la siguiente consulta,

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

Esta consulta eliminará todos los estudiantes que tengan nombre, Student1

** softDelete y restaurar **

Se utiliza para eliminar los datos por software y puede restaurar el registro en función de la identificación del estudiante. El código de muestra es el siguiente:

await repository.softDelete(1);

Puede restaurar el registro del estudiante usando el siguiente comando:

await repository.restore(1);

Una opción alternativa para eliminar y restaurar es usar softRemove y recovermétodos. El código de muestra es el siguiente:

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

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

Y puede recuperarlos utilizando el método de recuperación como se especifica a continuación,

await repository.recover(entySoftRemove);

salvar

savese utiliza para guardar la entidad dada en la base de datos. La entidad de estudiante simple se puede guardar como se muestra a continuación:

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

Esto agregará un nuevo registro de estudiante a la base de datos.

eliminar

removese utiliza para eliminar la entidad dada de la base de datos. La entidad de estudiante simple se puede eliminar como se muestra a continuación:

await repository.remove(stud);

contar

countEl método devolverá el número de registros disponibles en la tabla y puede usarlo con fines de paginación. El código de muestra es el siguiente:

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

encontrar

findEl método se utiliza con fines de búsqueda. Obtiene todo el registro de la base de datos como se muestra a continuación:

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

Encuentra uno

Similar a findmétodo, pero devuelve el primer registro coincidente. El código de muestra es el siguiente:

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

claro

clearEl método borra todos los datos de la tabla. El código de muestra es el siguiente:

await repository.clear();

EntityManager es parecido a Repositoryy se utiliza para administrar operaciones de base de datos como insertar, actualizar, eliminar y cargar datos. MientrasRepository maneja una sola entidad, EntityManager es común a todas las entidades y puede realizar operaciones en todas las entidades.

API de Entity Manager

Podemos acceder EntityManager utilizando getManager() método como se especifica a continuación -

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

Aprendamos el método más importante de EntityManager en este capítulo.

conexión

connectionEl método devuelve la conexión ORM de la base de datos a bases de datos específicas. El código de muestra es el siguiente:

const connection = manager.connection;

QueryRunner

queryRunnerEl método devuelve un objeto de ejecución de consultas personalizado y el administrador de la entidad lo utiliza para las operaciones de la base de datos. El código de muestra es el siguiente:

const queryRunner = manager.queryRunner;

transacción

Si se llaman varias solicitudes de base de datos, la transacción se ejecutará en una sola transacción de base de datos. El código de muestra para obtener la transacción es el siguiente:

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

consulta

queryEl método ejecuta consultas SQL. Consulta de inserción simple como se muestra a continuación:

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

insertar

insertEl método se utiliza para insertar una nueva entidad o matriz de entidades en la base de datos. El código de muestra es el siguiente:

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

actualizar

update se utiliza para actualizar los registros existentes en la base de datos.

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

Esta consulta funciona de manera similar a la siguiente consulta SQL,

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

Eliminar

El método de eliminación eliminará el registro especificado de la tabla,

await manager.delete(Student, 1);

Esto eliminará con la identificación 1 del registro del estudiante.

salvar

savese utiliza para guardar la entidad dada en la base de datos. La entidad de estudiante simple se puede guardar como se muestra a continuación:

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

Esto agregará un nuevo registro de estudiante a la base de datos. El método save insertará al estudiante, si el estudiante dado no existe en la base de datos. De lo contrario, guardar actualizará el registro del estudiante existente en la base de datos.

eliminar

removese utiliza para eliminar la entidad dada de la base de datos. La entidad de estudiante simple se puede eliminar como se muestra a continuación:

await manager.remove(stud);

contar

countEl método devolverá el número de registros disponibles en la tabla y puede usarlo con fines de paginación. El código de muestra es el siguiente:

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

encontrar

findEl método se utiliza con fines de búsqueda. Obtiene todo el registro de la base de datos como se muestra a continuación:

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

Encuentra uno

Similar a findmétodo, pero devuelve el primer registro coincidente. El código de muestra es el siguiente:

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

claro

El método clear borra todos los datos de la tabla. El código de muestra es el siguiente:

await manager.clear(Student);

El generador de consultas se utiliza para crear consultas SQL complejas de una manera fácil. Se inicializa desde el método Connection y los objetos QueryRunner.

Podemos crear QueryBuilder de tres formas.

Conexión

Considere un ejemplo simple de cómo usar QueryBuilder usando el método de conexión.

import {getConnection} from "typeorm"; 

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

Gerente de entidad

Creemos un generador de consultas usando el administrador de entidades de la siguiente manera:

import {getManager} from "typeorm"; 

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

Repositorio

Podemos usar el repositorio para crear un generador de consultas. Se describe a continuación,

import {getRepository} from "typeorm"; 

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

Alias

Los alias son los mismos que los de SQL. Creamos un alias para la tabla de Estudiantes usando QueryBuilder como se describe a continuación:

import {getConnection} from "typeorm"; 

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

Esta consulta es equivalente a,

select * from students as stud

Parámetros

Parametersse utilizan como marcadores de posición para los valores dinámicos de la consulta. En muchos casos, la consulta para encontrar un objeto de entidad diferente será la misma excepto los valores. Por ejemplo, la consulta para encontrar un estudiante diferente es la misma exceptoStudent IDdatos. En este caso, podemos usar el parámetro paraStudent ID y luego cambie el parámetro para obtener los diferentes objetos de los estudiantes.

Otro uso importante de los parámetros es evitar la inyección de SQL. Es una de las brechas de seguridad importantes en la aplicación web moderna. Al usar el parámetro en la consulta, podemos sobrevivir a los ataques de inyección SQL.

Otro uso importante de los parámetros es evitar la inyección de SQL. Es una de las brechas de seguridad importantes en la aplicación web moderna. Al usar el parámetro en la consulta, podemos sobrevivir a los ataques de inyección SQL.

Por ejemplo

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

Aquí,

: id - nombre del parámetro.

{id: 1}: valor del parámetro

Añadiendo expresión

Esta sección explica cómo usar expresiones.

dónde

where se utiliza para filtrar los registros si la condición coincide.

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

Esta consulta es equivalente a,

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

También podemos usar las condiciones AND, OR, NOT, IN en el interior.

teniendo

La expresión de tener simple se define a continuación:

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

Esta consulta es equivalente a,

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

orderBy

orderby se utiliza para ordenar los registros según el campo.

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

Esta consulta es equivalente a,

select * from students student order by student.name;

agrupar por

Se utiliza para agrupar los registros según la columna especificada.

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

Esta consulta es equivalente a,

select * from students student group by student.id;

límite

Se utiliza para limitar la selección de filas. A continuación, el ejemplo muestra cómo utilizar el límite en el generador de consultas,

createQueryBuilder("student") .limit(5)

Esta consulta es equivalente a,

select * from students student limit 5;

compensar

El desplazamiento se usa para especificar cuántas filas se omiten el resultado. Se define a continuación:

createQueryBuilder("student") .offset(5)

Esta consulta es equivalente a,

select * from students student offset 5;

Uniones

La cláusula de unión se utiliza para combinar filas de dos o más tablas, según una columna relacionada. Considere las dos entidades:

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

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

Realicemos una combinación izquierda simple usando la siguiente consulta:

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

Esta consulta es equivalente a,

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

Del mismo modo, también podemos probar la unión interna.

Únete sin selección

Podemos unir datos sin usar select. Probemos este ejemplo usando Inner join de la siguiente manera:

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

La consulta anterior es equivalente a:

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

Paginación

Si tiene más datos en su aplicación, necesita funciones de paginación, deslizador de página o desplazamiento.

Por ejemplo, si desea mostrar los primeros cinco proyectos de estudiantes en su aplicación,

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

subconsultas

Se llama consulta dentro de otra consulta o consulta anidada. Usamos subconsultas en las expresiones FROM, WHERE y JOIN.

A continuación se muestra un ejemplo simple:

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 escondido

Si alguno de los campos de su columna está marcado como {select: false}, esa columna se considera una columna oculta. Considere la siguiente entidad:

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

@Entity() 
export class Student {

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

Aquí,

address el campo está marcado como hidden. Nosotros podemos usaraddSelectmétodo para recuperar la información de la columna. Se define a continuación,

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

getSql ()

Este método se utiliza para obtener la consulta SQL generada por el generador de consultas. Se define a continuación:

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

La manipulación de datos se utiliza para administrar y ver datos. Esta sección explica cómo acceder a las consultas de la base de datos, como insertar, actualizar, seleccionar y eliminar consultas utilizando QueryBuilder. Repasemos uno por uno en detalle.

Crear consulta de inserción

Creemos una entidad de Cliente de la siguiente manera:

Customer.ts

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

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

Agreguemos los siguientes cambios en index.ts de la siguiente manera:

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

Ahora, inicie su aplicación usando el siguiente comando:

npm start

Salida

Podrías ver el siguiente resultado en tu pantalla:

Ahora abra su servidor mysql, tabla insertada con dos campos como se muestra a continuación:

Crear consulta de actualización

Última sección, hemos insertado dos filas de datos. Veamos cómo funciona la consulta de actualización. Agregue los siguientes cambios en index.ts de la siguiente manera:

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

Ahora, inicie su aplicación usando el siguiente comando:

npm start

Podrías ver el siguiente resultado en tu pantalla:

La tabla Mysql se modifica como se muestra a continuación:

Crear consulta de selección

selectLa consulta se utiliza para mostrar los registros de la tabla. Agreguemos el siguiente código enindex.ts como sigue -

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

Podrías ver el siguiente resultado en tu pantalla:

donde expresión

Agreguemos la expresión where en la consulta para filtrar los clientes. El código de muestra es el siguiente:

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

El programa anterior devolverá los primeros registros de identificación. Podrías ver el siguiente resultado en tu pantalla,

Del mismo modo, también puede probar otras expresiones.

Crear consulta de eliminación

Última sección, hemos insertado, actualizado y seleccionado datos. Veamos cómo funciona la consulta de eliminación. Agregue los siguientes cambios en index.ts de la siguiente manera:

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

Podrías ver el siguiente resultado en tu pantalla:

Y su tabla mysql se modifica de la siguiente manera:

Generalmente, la transacción es una unidad lógica responsable de la ejecución de la recuperación y actualización de datos. Esta sección explica las transacciones en detalle.

Creando transacciones

Podemos crear una transacción utilizando una conexión o EntityManage. El siguiente ejemplo se utiliza para especificar crear conexión y guardar datos dentro de ella.

import {getConnection} from "typeorm"; 

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

   await connection.manager.save(students); 

});

EntityManager se muestra a continuación -

import {getManager} from "typeorm";

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

Decoradores

Tenemos tres tipos de decoradores relacionados con transacciones en TypeORM.

  • @Transaction - Envuelve toda la ejecución en una sola transferencia de base de datos.
  • @TransactionManager- Se utiliza para ejecutar consultas dentro de la transacción. Se define a continuación,
@Transaction({ isolation: "SERIALIZABLE" }) 

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

Aquí,

Nosotros usamos SERIALIZABLE nivel de aislamiento para la transacción.

  • @TransactionRepository- Se utiliza para inyectar transacciones en el repositorio. Se define a continuación,
@Transaction() save(student: Student, @TransactionRepository(Student) studentRepository: 
Repository<Student>) { 
   return studentRepository.save(student); 
}

Transacción en QueryRunner

QueryRunner se utiliza para ejecutar todas las consultas de la base de datos. Tiene conexión de base de datos única. La transacción de la base de datos se puede organizar mediante QueryRunner . Realicemos una sola transacción usando 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");

Ahora, comience la transacción utilizando la siguiente declaración:

await queryRunner.startTransaction();

Luego, confirme y revierta la transacción utilizando la siguiente declaración,

try { 
   await queryRunner.commitTransaction(); 
}

Si hay algún error, es manejado por catch (),

catch (err) { 

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

Ahora, suelte el queryRunner como se muestra a continuación:

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

En general, Indexinges un proceso para optimizar el rendimiento de una base de datos optimizando el almacenamiento de datos. Se utiliza para localizar y acceder rápidamente a los datos en una base de datos. Esta sección explica cómo usar el índice en TypeORM. Los índices se clasifican en diferentes tipos. Repasemos uno por uno en detalle.

Índices de columna

Podemos crear un índice para una columna en particular usando @Index. Considere un ejemplo de entidad Cliente como se muestra a continuación y el índice definido parafirstName columna,

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 permitir especificar el nombre de un índice también -

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

Índices únicos

Para especificar restricciones únicas en su columna, use la siguiente propiedad:

{ unique: true }

Por ejemplo, a continuación se muestra el código para especificar un índice único para la columna Nombre:

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

Para aplicar índices para más de una columna, podemos especificarlo directamente después de @Entity (). El código de muestra es el siguiente:

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

Índices espaciales

El índice espacial permite acceder a objetos espaciales. MySQL y PostgreSQL admiten índices espaciales. Para habilitar índices espaciales en su columna, agregue la siguiente propiedad:

{ spatial: true }

El tipo espacial tiene varios subtipos, como geometría, punto, cadena de línea, polígono, etc. Por ejemplo, si desea agregar un tipo espacial de punto en su columna, utilice el siguiente código:

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

Deshabilitar la sincronización

Para deshabilitar la sincronización, use la siguiente opción en @Index decorador -

{ synchronize: false }

El detector de entidades se utiliza en entidades que admiten métodos personalizados y escuchan eventos específicos. Podemos definir cualquier método personalizado de entidad usando decoradores. Entendamos a los decoradores en breve.

  • @AfterLoad - Cuando la entidad se carga usando QueryBuilder o repositorio / administrador, se llamará a este método.
  • @BeforeInsert - Este método llamará antes de que se inserte la entidad usando el repositorio / administrador.
  • @AfterInsert - Este método llamará después de que la entidad se inserte usando el repositorio / administrador.
  • @BeforeUpdate - Este método lo llamará antes de que una entidad existente se actualice usando el repositorio / administrador.
  • @AfterUpdate - Llamará después de que se actualice una entidad.
  • @BeforeRemove - Llamará antes de que se elimine una entidad.
  • @AfterRemove - Llamará después de que se elimine una entidad.

Abonado

El suscriptor se usa para escuchar eventos de entidad específicos. Se implementa desdeEntitySubscriberInterface. Entendamos un ejemplo simple de cómo usar el detector de entidad en el suscriptor. Considere que la entidad Student se muestra a continuación:

Student.ts

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

@Entity() 
export class Student {     

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

Crear suscriptor de estudiante

El suscriptor se crea usando el siguiente comando:

typeorm subscriber:create -n StudentSubscriber

El comando anterior crea un directorio de suscriptores dentro de su proyecto src. Luego, el archivo StudentSubscriber.ts se crea dentro de su suscriptor. Podrías ver la siguiente respuesta,

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

Ahora muévase al archivo, puede ver la siguiente codificación:

StudentSubscriber.ts

import {EventSubscriber, EntitySubscriberInterface} from "typeorm"; 

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

Ahora, agregue los siguientes cambios en el archivo,

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

Aquí,

Hemos usado afterInsert()método para llamar al evento de entidad. Del mismo modo, también puede utilizar otros eventos. Ya hemos configurado el archivo ormconfig.json. Ahora, agregue los siguientes cambios enindex.ts archivo de la siguiente manera:

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

Después de ejecutar la aplicación, puede ver el siguiente resultado en su pantalla,

Inicio sesión

El registro de la base de datos es una parte importante del diseño de su solución de base de datos de alta disponibilidad porque los registros de la base de datos permiten recuperarse de una falla y permiten sincronizar las bases de datos primarias y secundarias.

Todas las bases de datos tienen registros asociados. Estos registros mantienen registros de los cambios en la base de datos. Si es necesario restaurar una base de datos a un punto más allá de la última copia de seguridad completa fuera de línea, se requieren registros para transferir los datos al punto de falla.

Opciones de registro

El registro se habilita agregando {logging: true} en la conexión de la base de datos. Las opciones de registro se clasifican en diferentes tipos. Son los siguientes:

query- devolver todas las consultas de registro. Se define como se indica a continuación:

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

error- Registros de retorno de todas las consultas fallidas y errores. Se define a continuación:

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

schema - Registros de retorno para el esquema.

warn - devolver advertencias internas de ORM.

info - Registros de mensajes informativos internos de ORM.

log - devolver mensajes de registro ORM internos.

Registrador personalizado

El registro personalizado es una opción de registro simple y altamente personalizable. Podemos crear nuestra propia clase de registrador usando el siguiente código:

import {Logger} from "typeorm"; 

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

La opción de conexión se especifica en ormconfig.json de la siguiente manera:

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

El idioma predeterminado admitido por TypeORM es TypeScript. Dado que TypeScript admite tipos, clases y decoradores estáticos, es fácil definir la entidad y sus atributos. Al mismo tiempo,JavaScript también es necesario en ciertos proyectos donde el idioma preferido es JavaScript. TypeORMtambién proporciona soporte completo para el lenguaje JavaScript. TypeORM admite los sabores es5 y es6 de JavaScript.

En este capítulo, aprendamos a escribir una aplicación TypeORM en JavaScript ES5 (ECMAScript 5).

Abra un símbolo del sistema y vaya a su espacio de trabajo.

cd /path/to/workspace/

Ejecute el siguiente comando para crear un proyecto TypeORM.

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

Abierto package.json archivo para eliminar las referencias de typecipt.

original

{ 
   "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" } 
}

actualizado

{ 
   "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" 
   } 
}

Aquí,

  • Retiró el devDependencies sección y paquete relacionado con mecanografiado en dependences sección.
  • Se modificó la secuencia de comandos de inicio para señalar código javascript en lugar de código mecanografiado.

Ejecute el siguiente comando para instalar los paquetes necesarios.

npm install

Eliminar tsconfig.json y archivo index.ts.

Elimine el archivo User.ts dentro de la carpeta de la entidad y luego cree la entidad de estudiante en formato json, student.json como se especifica a continuación -

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

Cree un nuevo archivo, src / index.js y coloque el siguiente código:

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

Aquí,

Hemos utilizado los mismos métodos typeORM, excepto los cambios mencionados a continuación,

  • Usado EntitySchema para configurar la entidad estudiante.
  • Se utilizaron bloques del concepto de Promesa de JavaScript (luego / captura / finalmente).

Ahora, ejecute la aplicación usando el siguiente comando:

npm start

La aplicación inserta la información del estudiante en la base de datos y luego busca a todos los estudiantes en la base de datos y lo muestra en la consola como se muestra a continuación:

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

Este capítulo explica el amplio soporte de base de datos MongoDB proporcionado por TypeORM. Con suerte, hemos instalado mongodb usando npm. Si no está instalado, use el siguiente comando para instalar el controlador MongoDB,

npm install mongodb --save

Creando un proyecto

Creemos un nuevo proyecto usando MongoDB de la siguiente manera:

typeorm init --name MyProject --database mongodb

Configurar ormconfig.json

Configuremos las opciones de host, puerto y base de datos de MongoDB en el archivo ormconfig.json como se especifica a continuación:

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

Definir entidades y columnas

Creemos una nueva entidad llamada Student dentro de su directorio src. Las entidades y columnas son las mismas. Para generar la columna de clave primaria, usamos@PrimaryColumn o

@PrimaryGeneratedColumn. Esto se puede definir como @ObjectIdColumn. A continuación se muestra un ejemplo simple:

Student.ts

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

@Entity() 
export class Student {  

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

Para guardar esta entidad, abra el archivo index.ts y agregue los siguientes cambios:

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

Ahora, inicie su servidor y obtendrá la siguiente respuesta:

npm start

EntityManager de MongoDB

También podemos usar EntityManager para obtener datos. A continuación se muestra un ejemplo simple:

import {getManager} from "typeorm";

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

Del mismo modo, también podemos utilizar el repositorio para acceder a los datos.

import {getMongoRepository} from "typeorm"; 

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

Si desea filtrar los datos usando la misma opción de la siguiente manera:

import {getMongoRepository} from "typeorm"; 

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

Como vimos en este capítulo, TypeORM facilita el trabajo con el motor de base de datos MongoDB.

Express es uno de los marcos de JavaScript más populares para crear aplicaciones web. Aprendamos a usarTypeORM junto con el marco expreso en este capítulo.

Creando una aplicación simple

TypeORM CLI proporciona una opción fácil para crear una aplicación web rápida de trabajo completa (aplicación Restful API) integrada con TypeORM. El comando CLI para crear la aplicación es el siguiente:

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

El comando anterior creará una nueva aplicación web en la carpeta typeorm-express-sample. La estructura de la aplicación es la siguiente:

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

Aquí,

Tal como lo conocemos, ormconfig.json es el TypeORMarchivo de configuración. El código es el siguiente,

{ 
   "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" 
   } 
}

Aquí, cambie la configuración de la base de datos para que coincida con la configuración de su base de datos local.

package.json archivo es la configuración principal de la aplicación.

tsconfig.json El archivo contiene la configuración relacionada con TypeScript.

entity carpeta contiene el TypeORMmodelos. CLI creará un modelo de usuario predeterminado y es el siguiente:

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

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

controllercarpeta contiene los controladores express. CLI crea un controlador de API de usuario predeterminado con agregar / listar / eliminar detalles de usuario. El código es el siguiente:

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

Aquí,

all El método se utiliza para recuperar todos los usuarios de la base de datos.

one El método se usa para buscar un solo usuario de la base de datos usando user id

save El método se utiliza para guardar la información del usuario en la base de datos.

delete El método se usa para eliminar al usuario de la base de datos usando user id

routes.ts El archivo asigna los métodos del controlador de usuario a la URL adecuada y el código es el siguiente:

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

Aquí,

/ users url se asigna al controlador de usuario. Cada publicación, obtención y eliminación de verbos se asignan a diferentes métodos.

Finalmente, index.tses nuestro principal punto de entrada a la aplicación web. El código fuente es el siguiente:

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

Aquí, la aplicación configura las rutas, inserta dos usuarios y luego inicia la aplicación web en el puerto 3000 . Podemos acceder a la aplicación enhttp://localhost:3000

Para ejecutar la aplicación, siga los pasos a continuación:

Instalemos los paquetes necesarios usando el siguiente comando:

npm install

Salida

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

Ejecute el siguiente comando para iniciar la aplicación.

npm start

Salida

> [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

Permítanos acceder a nuestra API de aplicación web usando el comando curl como se muestra a continuación:

curl http://localhost:3000/users

Aquí,

curl es una aplicación de línea de comandos para acceder a la aplicación web desde el símbolo del sistema. Es compatible con todos los verbos HTTP como obtener, publicar, eliminar, etc.

Salida

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

Para obtener el primer registro, podemos usar el siguiente comando:

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

Salida

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

Para eliminar un registro de usuario, podemos usar el siguiente comando:

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

Como vimos en este capítulo, TypeORM se puede integrar fácilmente en la aplicación express.

Las migraciones son como el control de versiones de su base de datos. Se utiliza para modificar y compartir el esquema de la base de datos de la aplicación. Esta sección explica cómo funcionan las migraciones en TypeORM.

Creando nueva migración

Para crear una nueva migración, primero debemos configurar la conexión en ormconfig.json. Se define a continuación:

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

Aquí,

  • migrationsTableName - hace referencia al nombre de la tabla de migración.
  • migrations - TypeORM carga migraciones desde un directorio dado.
  • cli - indica que la migración se creará dentro del directorio específico.

Crear entidad de libro

Creemos una entidad llamada Book entidad dentro src/entity/Book.ts como sigue -

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

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

Ejecute CLI para crear una nueva migración

Ahora, podemos ejecutar una nueva migración usando CLI de la siguiente manera:

Sintaxis

typeorm migration:create -n <migration-name>

Ejemplo

typeorm migration:create -n myMigration

Después de ejecutar el comando anterior, podría ver la siguiente respuesta:

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

Ahora, muévete adentro src/migration/1587101104904-myMigration.ts archivo se parece a esto.

import {MigrationInterface, QueryRunner} from "typeorm"; 

export class myMigration1587101104904 implements MigrationInterface {      

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

Aquí,

Tenemos dos métodos up y down. up El método se utiliza para agregar cambios a la migración y down El método se utiliza para revertir los cambios en su migración.

Agreguemos up método dentro myMigration.ts archivo como se especifica a continuación -

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

Aquí,

Hemos agregado una nueva columna price dentro bookmesa. Ahora, ejecute la CLI para agregar los cambios anteriores.

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

El comando anterior ejecuta migraciones y las ejecuta en una secuencia. Ahora, puede ver los siguientes cambios en su pantalla:

Salida

Ahora abra su servidor mysql, se agrega una nueva columna. Se muestra a continuación:

De manera similar, podemos modificar el tipo de datos del título de la columna a varchar (30) de la siguiente manera,

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

Ahora, ejecute el mismo comando y podrá realizar los siguientes cambios:

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

Salida

Book la tabla se modifica como,

Revertir la migración

Agreguemos el siguiente código dentro down método para revertir la migración -

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

Ahora, ejecute el siguiente comando para revertir todos los cambios:

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

Podrías ver la siguiente respuesta:

Salida

Book la tabla se modifica como,

Salida

Como vimos en este capítulo, TypeORM facilita la escritura de un script de migración de base de datos.

Esta sección explica en detalle los comandos CLI de TypeORM.

Crear proyecto TypeORM

typeorm inites la forma más fácil y rápida de configurar un proyecto TypeORM. Puede crear un nuevo proyecto como,

typeorm init --name Demoproject --database mysql

Después de ejecutar el comando, obtendrá el siguiente resultado en su pantalla:

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

Crea una entidad

Para crear una nueva entidad usando CLI como,

typeorm entity:create -n Person

Ahora, la entidad Person se crea dentro del directorio src de su proyecto.

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

Si tiene una estructura de proyecto de varios módulos con varias entidades en diferentes directorios, puede usar el siguiente comando,

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

Crea un nuevo suscriptor

Para crear un nuevo suscriptor usando CLI de la siguiente manera:

typeorm subscriber:create -n PersonSubscriber

Podrías ver la siguiente respuesta:

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

Crea migraciones

Puede crear una nueva migración utilizando CLI como se menciona a continuación:

typeorm migration:create -n PersonMigration

El comando anterior creó un directorio de migración dentro de su proyecto src. Los archivos de migración se almacenan en su interior.

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

Esquema de base de datos

Para sincronizar un esquema de base de datos, use el siguiente comando:

typeorm schema:sync

Para eliminar completamente un esquema de base de datos, use el siguiente comando:

typeorm schema:drop

Consultas SQL

Si desea ejecutar consultas SQL, podemos ejecutarlas directamente desde aquí. Por ejemplo, para mostrar todos los registros de clientes, utilice la siguiente consulta:

typeorm query "select * from customers"

Si desea borrar todo lo almacenado en el caché. Puedes hacerlo usando el siguiente comando:

typeorm cache:clear

Conclusión

TypeORM es un excelente marco ORM de código abierto para crear aplicaciones escalables y de alta calidad, desde aplicaciones a pequeña escala hasta aplicaciones empresariales a gran escala con múltiples bases de datos.