TypeORM - Generador de consultas

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 del parámetro 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 del parámetro 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 usar el límite en el generador de consultas,

createQueryBuilder("student") .limit(5)

Esta consulta es equivalente a,

select * from students student limit 5;

compensar

La compensación se usa para especificar cuántas filas se omitirán en 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();