我在继续我最后一个关于jOOQ的问题。在Hibernate模型中,使用了过滤器注释,我想将这个相同的“默认过滤器”应用于jOOQ查询。当我将jOOQ查询传递给nativeQuery(org.jOOQ.query query,Class
这就是我尝试过的:
private static <E> SelectConditionStep<Record> applyDefaultFilters(Class<E> type, SelectConditionStep<Record> query)
{
if (BaseOrganizationModel.class.isAssignableFrom(type)) {
query
.getQuery()
.addConditions(
query
.getQuery()
.asTable()
.field("organization_id", Long.class)
.eq(currentOrganization().id));
if (SoftDeletableModel.class.isAssignableFrom(type)) {
query
.getQuery()
.addConditions(query.getQuery().asTable().field("deleted", Boolean.class).eq(false));
}
}
return query;
}
结果就是这个SQL,不是我想要的,我要它过滤对应的表。
select distinct `EventGroup`.*
from `EventGroup`
where (
...
and `alias_100341773`.`organization_id` = ?
and `alias_17045196`.`deleted` = ?
)
我想要这个
select distinct `EventGroup`.*
from `EventGroup`
where (
...
and `EventGroup`.`organization_id` = ?
and `EventGroup`.`deleted` = ?
)
这有可能吗?如果没有,还有什么其他可能的路线?(除了明显的将表格传递给函数之外)
jOOQ 3.16引入了一个新的实验性(截至3.16)查询对象模型API,可以遍历。
在任何Select
上,只需调用Select.$from()
即可访问包含的表列表的不可修改视图。
每次您尝试修改现有查询时,请问自己,是否有更优雅的方法使用更实用、更不可变的方法进行动态SQL?与其将额外的谓词附加到查询中,为什么不从函数中生成谓词?
private static Condition defaultFilters(Class<?> type, Table<?> table) {
Condition result = noCondition();
if (BaseOrganizationModel.class.isAssignableFrom(type)) {
result = result.and(table.field("organization_id", Long.class)
.eq(currentOrganization().id));
if (SoftDeletableModel.class.isAssignableFrom(type))
result = result.and(not(table.field("deleted", Boolean.class)))
}
return result;
}
现在,当您构建查询时,您可以添加过滤器:
ctx.select(T.A, T.B)
.from(T)
.where(T.X.eq(1))
.and(defaultFilters(myType, T))
.fetch();
如果你真的想改变你的查询(例如,在一个用于所有查询的实用程序中),那么转换方法可能更合适。有不同的方法来实现这一点。
使用视图
一些RDBMS可以访问视图中的会话变量。在Oracle中,您可以在视图内部的organization_id
中设置一些SYS_CONTEXT
变量,然后只查询(可能是可更新的)视图,而不是直接查询表。不幸的是,MySQL不能做等效的事情,请参阅MYSQL中是否有与ORACLESYS_CONTEXT('USERENV','OS_USER')等效的东西?
我在这篇博文中描述了这种方法。这种方法的优点是您永远不会忘记设置谓词(您可以使用CI/CD测试验证您的视图源代码),如果您忘记设置会话上下文变量,视图将不会返回任何数据,因此它是一种非常安全的方法。
与AND CHECK OPTION
子句一起,您甚至可以防止插入错误的organization_id
,从而提高安全性。
在jOOQ中使用VisitListener
这是在jOOQ中实现这一点的最强大的方法,这正是您想要的,但对于所有边缘情况来说,这也是一种非常棘手的方法。请参阅这篇关于在jOOQ中实现行级安全性的文章。从jOOQ 3.16开始,将有更好的方法通过https://github.com/jOOQ/jOOQ/issues/12425.
注意,它不适用于不使用任何jOOQ查询部分的普通SQL模板,也不适用于基于JDBC的查询或系统中可能存在的其他查询,因此请小心使用这种方法,因为可能会从其他组织泄漏数据。
当然,您也可以在JDBC层上实现这一步骤,使用jOOQ的ParsingConnection或ParsingDataSource,这样您还可以拦截第三方SQL并附加谓词。
这可以适用于所有DML语句,包括UPDATE
,DELETE
。对于INSERT
来说有点困难,因为您必须将INSERT... VALUES
转换为INSERT... SELECT
,或者如果有人想插入错误的organization_id
,则抛出异常。
在jOOQ中使用ExecuteListener
与上面的VisitListener方法相比有点黑客化,但通常更容易正确,只需正则表达式将所有语句的WHERE子句替换为WHERE organization\u id=…和ExecuteListener中的。
为了安全起见,您可以拒绝没有WHERE子句的所有查询,或者做一些额外的技巧,在正确的位置添加WHERE子句,以防没有。
使用jOOQ与Hibernate的过滤器等效
jOOQ与Hibernate的过滤器等价于表。其中(条件)子句。这不是完全等效的,您必须防止直接访问代码库中的T,并确保用户仅通过用T替换T的方法访问T。其中(defaultFilters(myType,T))。
这种方法目前失去了表的类型安全性,请参阅:https://github.com/jOOQ/jOOQ/issues/8012
我有两个IP的主节点和工作节点?我需要使用这些部署一些服务。我对kubernetes一无所知,什么是主节点和工作节点? 我该如何开始?
我正在研究Blob,我注意到当你有一个ArrayBuffer时,你可以很容易地将它转换成Blob,如下所示: 我现在的问题是,有没有可能从一团变成一团?
我遵循了下一个教程:http://cwbuecheler.com/web/tutorials/2014/restful-web-app-node-express-mongodb/ 过了几天,我就把一切都做好了,但是更新用户数据库是读者自己的事。 我已经编辑了翡翠模板,并添加了一些javascript,用于更新链接上的点击事件。我甚至可以从列出的测试用户那里检索用户ID。用警报测试了这个,可以了。
如何从(在清单中)使用java?
问题内容: 因此,我试图在Eclipse中的已编译.class文件上运行“ javah”工具,但我不知道如何执行此操作。我发现的示例只是简单地说了“在类上运行javah …”,但我真的不知道在Eclipse中哪里可以找到这样的命令行。 如果有人可以给我一套愚蠢的证明说明,让我在Eclipse中完成这项工作,我将不胜感激。 谢谢 :) 问题答案: AFAIK Eclipse在默认情况下不集成java
问题内容: 我一直在尝试了解如何开始编写和运行JUnit测试。 当我阅读本文时: http://junit.sourceforge.net/doc/testinfected/testing.htm 我到达页面的中间,他们写道:“ JUnit带有图形界面来运行测试。在窗口顶部的字段中输入测试类的名称。按Run(运行)按钮。” 我不知道如何启动该程序。我什至不知道它在哪个包中,或者您如何从IDE运行库