Tom*_*mmy 16 sql typescript typeorm
我有多个嵌套的 where 条件,并且希望生成它们而无需使用 typeORM 进行太多代码重复。
SQL where 条件应该是这样的:
WHERE "Table"."id" = $1
AND
"Table"."notAvailable" IS NULL
AND
(
"Table"."date" > $2
OR
(
"Table"."date" = $2
AND
"Table"."myId" > $3
)
)
AND
(
"Table"."created" = $2
OR
"Table"."updated" = $4
)
AND
(
"Table"."text" ilike '%search%'
OR
"Table"."name" ilike '%search%'
)
Run Code Online (Sandbox Code Playgroud)
但似乎FindConditions不可能让它们嵌套,所以我必须AND在 FindConditions 数组中使用所有可能的组合。并且不可能将其拆分为.where()并.andWhere()导致andWhere无法使用对象文字。
是否有另一种可能性可以在不使用原始 SQL 的情况下使用 typeORM 实现此查询?
Suf*_*ane 31
使用 queryBuilder 时,我建议Brackets
按照 Typeorm 文档中所述使用: https: //typeorm.io/#/select-query-builder/adding-where-expression
你可以这样做:
createQueryBuilder("user")
.where("user.registered = :registered", { registered: true })
.andWhere(new Brackets(qb => {
qb.where("user.firstName = :firstName", { firstName: "Timber" })
.orWhere("user.lastName = :lastName", { lastName: "Saw" })
}))
Run Code Online (Sandbox Code Playgroud)
这将导致:
SELECT ...
FROM users user
WHERE user.registered = true
AND (user.firstName = 'Timber' OR user.lastName = 'Saw')
Run Code Online (Sandbox Code Playgroud)
Fun*_*nly 20
我认为您正在混合从 TypeORM 检索实体的两种方法,从存储库和查询生成器中查找。它们FindConditions用在 find 函数中。该andWhere函数由查询生成器使用。当构建更复杂的查询时,使用查询构建器通常更好/更容易。
使用查询构建时,您可以更自由地确保查询符合您的需要。您可以随意添加任何 SQL:
const desiredEntity = await connection
.getRepository(User)
.createQueryBuilder("user")
.where("user.id = :id", { id: 1 })
.andWhere("user.date > :date OR (user.date = :date AND user.myId = :myId)",
{
date: specificCreatedAtDate,
myId: mysteryId,
})
.getOne();
Run Code Online (Sandbox Code Playgroud)
请注意,根据您使用的数据库,您在此处使用的实际 SQL 需要兼容。因此,使用这种方法也可能存在缺点。您将把您的项目绑定到特定的数据库。如果您使用关系,请务必阅读有关可以设置的表的别名的信息,这会很方便。
您已经看到这不太舒服。这是因为find函数或更具体的findOptions函数正在使用对象来构建 where 子句。这使得实现适当的接口来并排实现嵌套AND和OR子句变得更加困难。为此(我认为)他们选择了拆分AND和OR子句。这使得界面更具声明性,并且意味着您必须将OR子句拉到顶部:
const desiredEntity = await repository.find({
where: [{
id: id,
notAvailable: Not(IsNull()),
date: MoreThan(date)
},{
id: id,
notAvailable: Not(IsNull()),
date: date
myId: myId
}]
})
Run Code Online (Sandbox Code Playgroud)
我无法想象看看所需查询的大小,这段代码会非常高效。
或者,您可以使用Raw查找助手。这将要求您重写每个字段的子句,因为您一次只能访问一个别名。您可以猜测列名或别名,但这将是非常糟糕的做法并且非常不稳定,因为您无法轻松直接控制它。
| 归档时间: |
|
| 查看次数: |
56366 次 |
| 最近记录: |