JOOQ中的行级安全性实现

我想使用JOOQ库在Java中实现oracle行级安全类function

以下是JOOQ查询代码的示例:

Result result = dslContext.select().from(Employee.EMPLOYEE).fetch(); 

上面的代码将生成如下SQL:

 select [dbo].[Employee].Id,... from [dbo].[Employee] 

我想添加一个where子句来过滤特定于用户安全性的数据,如下所示:

 select [dbo].[Employee].Id,... from [dbo].[Employee] WHERE [dbo].[Employee].Security IN (1,2) 

显式谓词

除非我遗漏了一些不错的SQL Serverfunction,其中行/记录包含一个名为.Security的伪列来实现行级安全性,你应该能够简单地写

 dslContext.select() .from(EMPLOYEE) .where(EMPLOYEE.SECURITY.in(1, 2)) .fetch(); 

有关jOOQ谓词构建的更多信息,请参阅此处的手册:

尤其是IN谓词:

使用jOOQ的ExecuteListener的一般解决方案

鉴于您的意见,您正在寻找一种通用方法来修补所有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)); } } } 

当然,上面还有改进的余地。 随意讨论用户组的用例

使用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) 

通过适当的授权,您可以隐藏开发人员的表格,确保他们只使用所需谓词的视图始终到位