我们以前使用的框架有一种机制,可以自动扩展SQL以过滤掉逻辑上删除的行。有没有办法也使用 jOOQ 实现这一点?
这个想法是:
- 通过
FROM
和JOIN
部分找出所有相关的表(不需要更复杂的逻辑)。 - 确定它们是否是逻辑可删除表(我们已经有了自己的元数据)。 如果
- 尚未给出删除,请使用
deleted = 0
扩展JOIN ... ON ...
部分。 - 添加/扩展
WHERE
部分,如果尚未为主表提供删除,则deleted = 0
。
最初有希望的方式似乎是QOM
(https://blog.jooq.org/traversing-jooq-expression-trees-with-the-new-traverser-api/)。 但是,如果我理解正确,它还没有准备好满足此要求,因为它不会遍历到JOIN
部分。 此外,由于它是实验性的,因此可能会有风险(?是否有一个粗略的时间/版本时间表,或者将来太不可预见了?
使用addConditions
扩展WHERE
部分(无需现有检查)非常容易。 但是对JOIN ... ON ...
部分做同样的事情?
由于jOOQ不允许扩展某些类,因为它们被标记为final(并不意味着批评,因为有可以理解的原因),并且Java不支持像C#这样的扩展方法,到目前为止我能想到的唯一解决方案是我们有自己的顶级选择方法来完成这一切。
例: selectFromWhereNotDelete(table1, table2, table3) - 选择语句的其余部分可以通过流畅的API添加>
它根据我们的元数据添加正确的连接条件。此外,它还确定表在逻辑上是否可删除,并相应地在所有位置添加deleted = 0
。这是实现的,并且有效。但它完全打破了已知的标准SQL语法。特别是如果您只想选择某些列和/或扩展JOIN ... ON ...
部分。我也完成了这项工作,但同样需要每个表参数的特殊语法(包装类/方法)。这意味着在编写代码时必须在SQL部分之间跳转。
另一种方法是自己实现所有涉及的jOOQ类作为包装器,以便能够使用所需的方法扩展它们。 我抓挠了一下,因为我发现它太乱了(太多的层,太多的代码,如果将来jOOQ改变,太脆了)。
似乎有人想到在某个时候(https://github.com/jOOQ/jOOQ/issues/2683)在jOOQ中实现软删除功能。
但是我错过了什么吗?已经有更好/更简单的方法了吗?
有没有办法用jOOQ来实现这一点?
即使在所有这些功能可用之前,您也可以使用现有的VisitListener
SPI 自行实现它。这篇博文中给出了一个示例,展示了如何使用VisitListener
通过 jOOQ 实现行级安全性。实现细节对于堆栈溢出答案来说太复杂了,尽管博客文章将为您提供足够的想法。
最初有希望的方式似乎是QOM。但是,如果我理解正确,它还没有准备好满足此要求,因为它不会遍历到 JOIN 部分。
它将从 jOOQ 3.18 开始遍历JOIN
树,另请参阅 #13640 以获取更改列表。您今天已经可以访问 3.18.0-SNAPSHOT 构建版本:https://www.jooq.org/download/versions
此外,由于它是实验性的,因此可能会有风险(?
从 jOOQ 3.18 开始,QOM
API 在次要版本之间仍会受到(不兼容的)更改的影响。 例如,可能有
- 方法名称更改
- 类型层次结构更改(例如,不清楚
Select
是否应该设置操作(内部现状),或者是否需要新的、更高级别的类型)
你这边的风险可能是可以接受的。API 不会再消失了。许多客户已经像您一样依靠它来实现自定义 SQL 转换。
是否有一个粗略的时间/版本时间表,或者将来太不可预见了?
当然,没有承诺,但我强烈希望这个 API 能在 2023 年底之前完成。
似乎有过在某个时候在jOOQ中实现软删除功能的想法。
事实上,软删除将很快出现在下一个版本之一(3.19左右?)中:#2683。为了正确实现它,jOOQ首先需要一个强大的:
- 公共查询对象模型 (
QOM
) API QOM
遍历和替换功能- SQL 转换功能
即你自己发现的所有东西。但是,软删除很可能在上述所有内容都离开实验状态之前发布。