TypeORM - Construtor de Consultas

O construtor de consultas é usado para construir consultas SQL complexas de uma maneira fácil. Ele é inicializado a partir do método Connection e dos objetos QueryRunner.

Podemos criar o QueryBuilder de três maneiras.

Conexão

Considere um exemplo simples de como usar QueryBuilder usando o método de conexão.

import {getConnection} from "typeorm"; 

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

Gerente de entidade

Vamos criar um construtor de consulta usando o gerenciador de entidades da seguinte maneira -

import {getManager} from "typeorm"; 

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

Repositório

Podemos usar o repositório para criar o construtor de consulta. É descrito abaixo,

import {getRepository} from "typeorm"; 

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

Apelido

Aliases são iguais aos alias SQL. Criamos um alias para a tabela de Aluno usando QueryBuilder conforme descrito abaixo -

import {getConnection} from "typeorm"; 

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

Esta consulta é equivalente a,

select * from students as stud

Parâmetros

Parameterssão usados ​​como marcadores para os valores dinâmicos na consulta. Em muitos casos, a consulta para encontrar diferentes objetos de entidade será a mesma, exceto os valores. Por exemplo, a consulta para encontrar um aluno diferente é a mesma, exceto oStudent IDdados. Neste caso, podemos usar o parâmetro paraStudent ID e, em seguida, altere o parâmetro para obter os diferentes objetos de aluno.

Outro uso importante do parâmetro é evitar a injeção de SQL. É uma das violações de segurança importantes nos aplicativos da web modernos. Usando o parâmetro na consulta, podemos sobreviver aos ataques de injeção de SQL.

Outro uso importante do parâmetro é evitar a injeção de SQL. É uma das violações de segurança importantes nos aplicativos da web modernos. Usando o parâmetro na consulta, podemos sobreviver aos ataques de injeção de SQL.

Por exemplo

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

Aqui,

: id - nome do parâmetro.

{id: 1} - valor do parâmetro

Adicionando expressão

Esta seção explica como usar expressões.

Onde

where é usado para filtrar os registros se a condição for correspondida.

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

Esta consulta é equivalente a,

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

Também podemos usar as condições AND, OR, NOT, IN dentro.

tendo

Expressão simples é definida abaixo -

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

Esta consulta é equivalente a,

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

ordenar por

orderby é usado para classificar os registros com base no campo.

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

Esta consulta é equivalente a,

select * from students student order by student.name;

groupBy

É usado para agrupar os registros com base na coluna especificada.

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

Esta consulta é equivalente a,

select * from students student group by student.id;

limite

É usado para limitar a seleção de linhas. Abaixo, o exemplo mostra como usar o limite no construtor de consultas,

createQueryBuilder("student") .limit(5)

Esta consulta é equivalente a,

select * from students student limit 5;

Deslocamento

O deslocamento é usado para especificar quantas linhas devem ser ignoradas no resultado. É definido abaixo -

createQueryBuilder("student") .offset(5)

Esta consulta é equivalente a,

select * from students student offset 5;

junta-se

A cláusula de junção é usada para combinar linhas de duas ou mais tabelas, com base em uma coluna relacionada. Considere as duas 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[]; 
}

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

Vamos realizar a junção à esquerda simples usando a consulta abaixo -

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

Esta consulta é equivalente a,

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

Da mesma forma, podemos tentar junção interna também.

Junte-se sem seleção

Podemos juntar dados sem usar select. Vamos tentar este exemplo usando Inner join como segue -

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

A consulta acima é equivalente a -

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

Paginação

Se você tiver mais dados em seu aplicativo, você precisa de paginação, controle deslizante de página ou funções de rolagem.

Por exemplo, se você quiser mostrar os primeiros cinco projetos de alunos em seu aplicativo,

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

subconsultas

É chamado de consulta em outra consulta ou consulta aninhada. Usamos subconsultas nas expressões FROM, WHERE e JOIN.

Um exemplo simples é mostrado abaixo -

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 oculto

Se algum dos campos da sua coluna estiver marcado como {select: false}, essa coluna é considerada como coluna oculta. Considere a entidade abaixo -

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

@Entity() 
export class Student {

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

Aqui,

address campo está marcado como hidden. Podemos usaraddSelectmétodo para recuperar as informações da coluna. É definido abaixo,

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

getSql ()

Este método é usado para obter a consulta SQL gerada pelo construtor de consultas. É definido abaixo -

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