TypeORM框架中的 Find查询中的基础选项和进阶选项
所有存储库和管理器find
方法都接受,可用于查询所需数据的特殊选项,而无需使用QueryBuilder
就像语法糖,但是不是真的语法糖,方便使用
find()
方法用于查询数据库中的实体对象,它的参数是一个对象,包含查询的条件、排序方式、返回的实体数量、返回的实体的偏移量等信息。
基础选项
select
- 指定要查询的实体对象的属性
如果省略select
属性,则默认查询所有实体对象的所有属性
import { createConnection } from "typeorm";
import { User } from "./entity/User";
// 创建数据库
createConnection().then(async (connection) => {
// 获取数据库中的数据
const userRepository = connection.Repository(User);
// 查询User表中名为 firstName 和 lastName 列的数据,并返回
userRepository.find({ select: ["firstName", "lastName"] });
});
relations
- 查询结果中包含的关联实体对象
在返回的结果中,包含关联的实体对象(返回的是整个实体对象)
import { createConnection } from "typeorm";
import { User } from "./entity/User";
// 创建数据库
createConnection().then(async (connection) => {
// 获取数据库中的数据
const userRepository = connection.Repository(User);
// 查询与主实体对象(User)关联的`profile`、`photos`和`videos`实体对象
userRepository.find({ relations: ["profile", "photos", "videos"] });
});
如果需要在查询时,同时想加载关联的实体对象和它们的属性,用外连接leftJoinAndSelect()
方法或内连接innerJoinAndSelect()
方法,就会在结果中得到关联表对象的值。
join
- 指定关联实体对象的查询方式
alias
属性指定主实体对象的别名
leftJoinAndSelect
属性是一个对象,用于指定要查询的关联实体对象及其属性
import { createConnection } from "typeorm";
import { User } from "./entity/User";
// 创建数据库
createConnection().then(async (connection) => {
// 获取数据库中的数据
const userRepository = connection.Repository(User);
userRepository.find({
join: {
alias: "user",
leftJoinAndSelect: {
profile: "user.profile",
photo: "user.photos",
video: "user.videos"
}
}
});
});
在这个例子中,alias
属性的值为user
,表示查询的是userRepository
所管理的实体对象。leftJoinAndSelect
属性是一个包含profile
、photo
和video
属性的对象,每个属性都表示要查询的关联实体对象及其在查询结果中的别名。例如,"user.profile"
表示查询与user
实体对象关联的profile
实体对象,并将其在查询结果中的别名设置为profile
。
where
-查询实体的简单条件
where
的值是一个包含一个或多个查询条件的数组,每个条件可以是一个简单的对象,也可以是一个包含运算符的对象,还可以使用逻辑运算符和括号来组合多个条件。
// 查询 firstName 为 Timber 同时 lastName 为 Saw 的数据
userRepository.find({ where: { firstName: "Timber", lastName: "Saw" } });
查询嵌入实体列应该根据定义它的层次结构来完成
// 查询属性中的属性值,符合条件的数据
userRepository.find({ where: { name: { first: "Timber", last: "Saw" } } });
使用 OR 运算符查询
userRepository.find({
// 表示查询结果为,满足两个对象条件的其中一个即可
where: [{ firstName: "Timber", lastName: "Saw" }, { firstName: "Stan", lastName: "Lee" }]
// 表示要查询`age`大于18的实体对象
where: { age: MoreThan(18) }
});
order
- 选择排序
排序方式有两种:升序(ASC)和降序(DESC)
order
方法接受一个字符串、对象或数组参数,用于指定排序方式
// 按照`firstName`属性的升序排列查询结果
userRepository.find({ order: "firstName" })
// 按照`firstName`属性的升序和`lastName`属性的降序排列查询结果
userRepository.find({ order: { firstName: "ASC", lastName: "DESC" } })
// 按照`firstName`属性的升序和`lastName`属性的升序排列查询结果
userRepository.find({ order: ["firstName", "lastName"] })
skip
- 指定查询结果的起始位置
它的值为一个数字,表示要跳过的记录数,设置为0
表示从查询结果的第一条记录开始返回结果。
take
- 指定查询结果的数量(分页,设置每一页返回多少)
它的值为一个数字,表示要返回的记录数。设置为10
表示返回最多10
条记录。
需要注意的是,分页查询时应根据实际情况设置skip
和take
属性的值。如果不设置take
属性,则将返回所有满足条件的记录。如果设置skip
属性的值大于查询结果的总记录数,则将返回一个空数组。
userRepository.find({
order: {
columnName: "ASC"
},
skip: 0,
take: 10
});
- cache -启用或禁用查询结果缓存
userRepository.find({
// true查询结果缓存,false不缓存
cache: true
});
进阶选项
TypeORM 提供了许多内置运算符,可用于创建更复杂的查询
Not
- 表示不等于指定值
import { Not } from "typeorm";
// 查询 `Post` 实体对象中 `title` 不等于 `"About"` 的所有记录
const loadedPosts = await connection.getRepository(Post).find({
title: Not("About")
});
LessThan
- 小于指定值
import { LessThan } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `likes` 小于 `10` 的所有记录
likes: LessThan(10)
});
LessThanOrEqual
- 小于等于指定值
import { LessThanOrEqual } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `LessThanOrEqual` 小于等于 `10` 的所有记录
likes: LessThanOrEqual(10)
});
MoreThan
- 大于指定值
import { MoreThan } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `likes` 大于 `5` 的所有记录
likes: MoreThan(5)
});
MoreThanOrEqual
- 大于等于指定值
import { MoreThanOrEqual } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `likes` 大于等于 `5` 的所有记录
likes: MoreThanOrEqual(5)
});
Equal
- 等于指定值
import { Equal } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `likes` 等于 `8` 的所有记录
likes: Equal(8)
});
Like
- 指定字符串模式匹配
import { Like } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `title` 字符串中包含 `abc` 的所有记录
title: Like("% abc %")
});
ILike
- 表示指定(忽略字符串的大小写)模式匹配
import { ILike } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `title` 字符串中 忽略大小写后 包含 `abc` 的所有记录
title: ILike("% abc %")
});
Between
- 表示在指定范围内
import { Between } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `math`数值在 1到10 之间的所有记录
math: Between(1, 10)
});
In
- 表示查询属性值,是In数组中选项的记录
import { In } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `title`属性值为 "About2"和"About3" 的所有记录
title: In(["About2", "About3"])
});
Any
- 表示查询属性值等于指定数组中任意一个元素的记录
import { Any } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `Post` 实体对象中 `title`属性值为 "About2"或"About3" 的所有记录
title: Any(["About2", "About3"])
});
IsNull
表示为空NotNull
表示不为空Raw
内置运算符可以直接接受 SQL 字符串作为查询条件,可以实现更复杂的查询条件
import { Raw } from "typeorm";
const loadedPosts = await connection.getRepository(Post).find({
// 查询 `likes` 属性值加 1 等于 4 的所有记录
likes: Raw("1 + likes = 4")
});
总结性案例:
const queryBuild = db.manager
.getRepository(user)
.createQueryBuilder("f")
// 连接faqAnswers表,别名为 a,将user的tenantIds属性值,传入faqAnswers表
.leftJoinAndSelect("f.faqAnswers", "a", "a.tenantId in (:...tenantIds)", {
tenantIds,
})
// 连接faqRelations表,取别名为 r
.leftJoin("f.faqRelations", "r")
.leftJoin("a.faqLabels", "al")
// 查询`user`实体类的`id`属性等于`id`
.where("f.id = :id", { id })
// 指定查询返回的结果,就是几天表中的 下面的属性
.select([
"f.id",
"f.question",
"f.validBeginTime",
"f.validEndTime",
"f.link",
"f.status",
"f.CategoryId",
"f.tenantId",
"a.id",
"a.answer",
"a.link",
"a.status",
"a.FaqId",
"a.tenantId",
"al.LabelId",
]);
const faq: any & Faq = await queryBuild.getOne();
-
.getRepository(user)
使用user
实体类的仓库对象作为查询的起点,返回一个QueryBuilder
对象。 -
.createQueryBuilder("f")
在user
实体类的仓库对象上创建一个查询构建器对象,并指定别名为f
。 -
.leftJoinAndSelect("f.faqAnswers", "a", "a.tenantId in (:...tenantIds)", {tenantIds})
执行一个左连接,连接user
实体类的faqAnswers
属性,使用别名a
表示连接后的结果,"a.tenantId in (:...tenantIds)"
表示连接条件,将tenantIds
中的值作为连接条件的参数传入。 -
.leftJoin("f.faqRelations", "r")
执行一个左连接,连接user
实体类的faqRelations
属性,使用别名r
表示连接后的结果。 -
.leftJoin("a.faqLabels", "al")
执行一个左连接,连接faqAnswers
实体类的faqLabels
属性,使用别名al
表示连接后的结果。 -
.where("f.id = :id", { id })
添加查询条件,查询user
实体类的id
属性等于id
。 -
.select([...])
指定查询的结果集,包含了Faq
实体类和faqAnswers
实体类的所有属性,以及faqLabels
实体类的LabelId
属性。 -
const fff: any & user = await queryBuild.getOne();
执行查询并获取查询结果,将查询结果赋值给fff
变量。getOne()
方法表示只获取一条满足查询条件的数据,返回一个Promise
对象,查询结果的类型为any & user
,即user
实体类的所有属性加上any
类型。
如何连接到数据库
转载自:https://juejin.cn/post/7237830541176848444