如何用typeORM制作复杂的嵌套WHERE条件?

如何用typeORM制作复杂的嵌套WHERE条件?

本文介绍了如何用typeORM制作复杂的嵌套WHERE条件?的处理方法,对大家解决问题具有一定的参考价值

问题描述

我有多个嵌套的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%'
)

但使用FindConditions似乎不可能使它们嵌套,因此我必须在FindConditions数组中使用AND的所有可能组合。并且无法将其拆分为.where().andWhere(),原因是andWhere无法使用对象文本。

是否有其他可能在不使用原始SQL的情况下使用typeORM实现此查询?

推荐答案

我认为您混合了从TypeORM中检索实体的两种方法,find从存储库和查询构建器。FindConditions用于查找函数。andWhere函数由查询构建器使用。在生成更复杂的查询时,使用查询生成器通常更好/更容易。


Query builder

使用查询构建时,您可以更自由地确保查询符合您的要求。您可以在其中随意添加任何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();
请注意,根据您使用的数据库,您在这里使用的实际SQL需要是兼容的。随之而来的也可能是使用这种方法的回落。您将把您的项目绑定到特定的数据库。如果您使用关系,请务必阅读有关aliases可以设置的表的信息,这将非常方便。

 


Repository

您已经看到,这不是很舒服。这是因为find函数或更具体地说findOptions使用对象来构建WHERE子句。这使得实现适当的接口来同时实现嵌套的ANDOR子句变得更加困难。在那里(我假设)他们选择了拆分ANDOR子句。这使得接口更具声明性,并意味着您必须将OR子句放在顶部:

const desiredEntity = await repository.find({
  where: [{
    id: id,
    notAvailable: Not(IsNull()),
    date: MoreThan(date)
  },{
    id: id,
    notAvailable: Not(IsNull()),
    date: date
    myId: myId
  }]
})

我无法想象查看所需查询的大小时,此代码会有很高的性能。

或者,您可以使用RawFind帮助器。这将要求您按字段重写子句,因为您一次只能访问一个别名。您可以猜测列名或别名,但这将是非常糟糕的做法,而且非常不稳定,因为您不能直接轻松地控制它。

posted on 2024-03-22 19:09  漫思  阅读(152)  评论(0编辑  收藏  举报

导航