gpt4 book ai didi

java - Jooq 中的条件查询日志记录

转载 作者:行者123 更新时间:2023-11-30 10:28:35 25 4
gpt4 key购买 nike

我们有一个用于记录数据库查询的自定义执行监听器,我们如何过滤掉仅针对特定表名记录的查询?目前,每个执行的查询都会被记录下来。

这是我们当前的监听器。

@Override
public void executeStart(ExecuteContext ctx) {
// Create a new DSLContext for logging rendering purposes
// This DSLContext doesn't need a connection, only the SQLDialect...
Settings setting = new Settings();
setting.withRenderFormatted(true);
setting.setExecuteLogging(true);
StringBuilder message = new StringBuilder();
DSLContext create = DSL.using(ctx.configuration().dialect(),
// ... and the flag for pretty-printing
new Settings().withRenderFormatted(true));
// If we're executing a query
if (ctx.query() != null && ENABLE_LOGGING) {
LOGGER.debug(message.append(DynamicApplicationConfig.getStringProperty("API_ENV","dev"))
.append(" - ")
.append(create.renderInlined(ctx.query())).toString());
}
// If we're executing a routine
else if (ctx.routine() != null && ENABLE_LOGGING) {
LOGGER.debug(message.append(DynamicApplicationConfig.getStringProperty("API_ENV","dev"))
.append(" - ")
.append(create.renderInlined(ctx.routine())).toString());
}
// If we're executing anything else (e.g. plain SQL)
else if (!StringUtils.isBlank(ctx.sql()) && ENABLE_LOGGING) {
LOGGER.debug(message.append(DynamicApplicationConfig.getStringProperty("API_ENV","dev"))
.append(" - ")
.append(ctx.sql()).toString());
}
}

最佳答案

稳健的解决方案:RenderContext

jOOQ 查询通过 RenderContext 生成 SQL 字符串API,这是传递给每个 jOOQ QueryPart 的 API,以生成 SQL 字符串内容和绑定(bind)变量。您可以自己实现并通过查询传递它,以便收集查询中包含的所有表。

请注意,RenderContext API 可能会在以后的次要版本中接收新方法,因此此实现可能会在不同版本之间中断。

稳健的解决方案:VisitListener

jOOQ 知道一个 VisitListener SPI,它允许您挂接到渲染生命周期。这个 SPI 的想法是能够修改生成的 SQL 内容 ( e.g. to implement more sophisticated multi-tenancy or row level security features )。

在您的情况下,您不会操作 jOOQ 表达式树,而只是收集所有正在呈现的表,并将它们存储在记录器可以访问的某个地方。

此解决方案可能会对渲染性能产生轻微影响。

快速而肮脏的解决方案:正则表达式

为了完整起见(我相信您自己已经想到了这一点),我列出了一个简单的解决方案,它只会在某个正则表达式与 SQL 字符串匹配时才记录消息,例如:

if (ctx.query() != null && ENABLE_LOGGING 
&& ctx.sql().matches("(?i:.*?\\bmy_table_name\\b.*)") {
LOGGER.debug(message.append(
DynamicApplicationConfig.getStringProperty("API_ENV","dev"))
.append(" - ")
.append(create.renderInlined(ctx.query())).toString());
}

当然,您的实际正则表达式可能更复杂

快速而肮脏的解决方案:使用反射访问内部结构

当然,您可以尝试访问 ctx.query() 的内部结构,其中存储了表引用。我不会在这里记录这个,因为它可能会发生变化,是内部的。

但为了完整起见,值得一提,因为对于您的情况,这可能是一个足够好的解决方案。

关于java - Jooq 中的条件查询日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44502786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com