📅  最后修改于: 2020-10-19 03:42:32             🧑  作者: Mango
使用查询构建器可以轻松地构建复杂的SQL查询。它是从Connection方法和QueryRunner对象初始化的。
我们可以通过三种方式创建QueryBuilder。
考虑一个简单的示例,该示例说明如何使用连接方法来使用QueryBuilder。
import {getConnection} from "typeorm";
const user = await getConnection() .createQueryBuilder()
.select("user")
.from(User, "user")
.where("user.id = :id", { id: 1 }) .getOne();
让我们使用实体管理器创建查询生成器,如下所示:
import {getManager} from "typeorm";
const user = await getManager() .createQueryBuilder(User, "user") .where("user.id = :id", { id: 1 }) .getOne();
我们可以使用存储库来创建查询构建器。如下所述,
import {getRepository} from "typeorm";
const user = await getRepository(User) .createQueryBuilder("user") .where("user.id = :id", { id: 1 }) .getOne();
别名与SQL别名相同。我们使用QueryBuilder为Student表创建别名,如下所述-
import {getConnection} from "typeorm";
const user = await getConnection() .createQueryBuilder()
.select("stud")
.from(Student, "stud")
此查询等同于,
select * from students as stud
参数用作查询中动态值的占位符。在许多情况下,查找不同实体对象的查询将与值相同。例如,查找不同学生的查询与学生ID数据相同。在这种情况下,我们可以将参数用于学生ID ,然后更改参数以获取不同的学生对象。
参数的另一个重要用途是防止SQL注入。它是现代Web应用程序中的重要安全漏洞之一。通过在查询中使用参数,我们可以抵抗SQL注入攻击。
参数的另一个重要用途是防止SQL注入。它是现代Web应用程序中的重要安全漏洞之一。通过在查询中使用参数,我们可以抵抗SQL注入攻击。
例如
"student.id = :id", { id: 1 }
这里,
:id-参数名称。
{id:1}-参数值
本节说明如何使用表达式。
如果条件匹配,则使用where过滤记录。
createQueryBuilder("student") .where("student.id = :id", { id: 1 })
此查询等同于,
select * from students student where student.id=1;
我们还可以在其中使用AND,OR,NOT,IN条件。
简单的表达式定义如下-
createQueryBuilder("student") .having("student.id = :id", { id: 1 })
此查询等同于,
select * from students student having student.id=1;
orderby用于基于字段对记录进行排序。
createQueryBuilder("student") .orderBy("student.name")
此查询等同于,
select * from students student order by student.name;
它用于根据指定的列对记录进行分组。
createQueryBuilder("student") .groupBy("student.id")
此查询等同于,
select * from students student group by student.id;
它用于限制行的选择。下面的示例显示了如何在查询构建器中使用限制,
createQueryBuilder("student") .limit(5)
此查询等同于,
select * from students student limit 5;
偏移量用于指定跳过结果的行数。它定义如下-
createQueryBuilder("student") .offset(5)
此查询等同于,
select * from students student offset 5;
join子句用于根据相关列合并两个或多个表中的行。考虑两个实体-
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[];
}
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;
}
让我们使用以下查询执行简单的左连接-
const student = await createQueryBuilder("student") .leftJoinAndSelect("student.projects", "project")
.where("student.name = :name", { name: "Student1" })
.getOne();
此查询等同于,
SELECT student.*, project.* FROM students student
LEFT JOIN projects project ON project.student = student.id
WHERE student.name = 'Student1'
同样,我们也可以尝试内部联接。
我们可以不使用select来联接数据。让我们使用内部连接尝试此示例,如下所示:
const student = await createQueryBuilder("student") .innerJoin("student.projects", "project")
.where("student.name = :name", { name: "student1" })
.getOne();
上面的查询等效于-
SELECT student.* FROM students student
INNER JOIN projects project ON project.student = student.id
WHERE student.name = 'Student1';
如果您的应用程序中有更多数据,则需要分页,页面滑块或滚动功能。
例如,如果您想在应用程序中显示前五个学生项目,
const students = await getRepository(Student) .createQueryBuilder("student") .leftJoinAndSelect("student.projects", "project")
.take(5)
.getMany();
它在另一个查询或嵌套查询中称为查询。我们在FROM,WHERE和JOIN表达式中使用子查询。
简单的例子如下所示-
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();
如果您的任何列字段都标记为{select:false},则该列被视为隐藏列。考虑以下实体-
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity()
export class Student {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column({select: false})
address: string;
}
这里,
地址字段标记为隐藏。我们可以使用addSelect方法从列中检索信息。定义如下
const student = await connection.getRepository(Student) .createQueryBuilder() .select("student.id", "student") .addSelect("student.address") .getMany();
此方法用于通过查询构建器获取生成的SQL查询。它定义如下-
const sql = createQueryBuilder("student") .where("student.name = :name", { name: "Student1" }) .orWhere("student.age = :age", { age: 14 })
.getSql();