显式谓词
除非我缺少一些不错的 SQL Server 功能,其中行/记录包含一个名为 .Security 的伪列来实现行级安全性,否则您应该能够简单地编写
dslContext.select()
.from(EMPLOYEE)
.where(EMPLOYEE.SECURITY.in(1, 2))
.fetch();
有关 jOOQ 谓词构建的更多信息,请参阅此处的手册:
尤其是IN 谓词:
使用 jOOQ 的 ExecuteListener 的一般解决方案
鉴于您的 cmets,您正在寻找一种通用方法来使用附加谓词修补所有 SQL 语句,无论特定程序员正在输入什么。
您可以使用 jOOQ 做到这一点,但请注意,如果程序员绕过 jOOQ,这只会帮助您执行谓词,而不是保证它。您可以做的是设置一个ExecuteListener,拦截renderStart() 事件以修补/替换正在执行的查询。大致如下:
@Override
public void renderStart(ExecuteContext ctx) {
if (ctx.query() instanceof Select) {
// Operate on jOOQ's internal query model
SelectQuery<?> select = null;
// Check if the query was constructed using the "model" API
if (ctx.query() instanceof SelectQuery) {
select = (SelectQuery<?>) ctx.query();
}
// Check if the query was constructed using the DSL API
else if (ctx.query() instanceof SelectFinalStep) {
select = ((SelectFinalStep<?>) ctx.query()).getQuery();
}
if (select != null) {
// Use a more appropriate predicate expression
// to form more generic predicates which work on all tables
select.addConditions(EMPLOYEE.SECURITY.in(1, 2));
}
}
}
当然,上述内容还有改进的余地。随时在user group
上讨论用例
使用 jOOQ 的 VisitListener 的通用解决方案
如果您愿意深入了解 jOOQ 的内部结构,还可以尝试实现 VisitListener 并实际转换 jOOQ 的 AST 表示形式的查询。这记录在这里:
使用视图的一般解决方案
虽然上述方法有效,但我个人建议您为此使用视图,并向开发人员隐藏实际的表格。示例:
CREATE VIEW v_employee AS
SELECT a, b, c, ...
FROM t_employee
WHERE t_employee.security in (1, 2)
通过适当的授权,您可以向开发人员隐藏表格,确保他们只会使用始终存在所需谓词的视图