Java 有没有办法检查jOOQ中的查询绑定值?

Java 有没有办法检查jOOQ中的查询绑定值?,java,sql,jooq,Java,Sql,Jooq,对于包含多个绑定参数的条件中的查询,我们有一个问题,因为它们有许多变体,并且很快会溢出查询缓存 我想签入sql语句的condition子句,并在为in子句指定的绑定值超过30个时引发异常 我可以用VisitListener吗 我可以使用org.jooq.VisitContextclause查找in或not in条件,但我无法在没有反射的情况下检查org.jooq.impl.InConditionvalues大小 现在我不得不这样做: public class MyVisitListener ex

对于包含多个绑定参数的条件中的查询,我们有一个问题,因为它们有许多变体,并且很快会溢出查询缓存

我想签入sql语句的condition子句,并在为in子句指定的绑定值超过30个时引发异常

我可以用VisitListener吗

我可以使用org.jooq.VisitContextclause查找in或not in条件,但我无法在没有反射的情况下检查org.jooq.impl.InConditionvalues大小

现在我不得不这样做:

public class MyVisitListener extends DefaultVisitListener {
    @Override
    public void visitStart(VisitContext context) {
        if (context.clause() == Clause.CONDITION_IN || context.clause() == Clause.CONDITION_NOT_IN) {
            try {
                Field field = context.queryPart().getClass().getDeclaredField("values");
                field.setAccessible(true);
                Object value = field.get(context.queryPart());
                if (((Object[]) value).length > 30) {
                    throw new IllegalArgumentException("More than 30 bind values specified!");
                }
            } catch (NoSuchFieldException | IllegalAccessException e) {
                //throw new UnknownException("Can`t check size of field 'values' in " + context.queryPart().getClass().getName(), e);
            }
        }
    }
}

jOOQ 3.10.8 pro有没有更方便的方法?

另一个选项,一个通常可以接受的解决问题的方法,是启用:

符合事实的 这不完全是你想要的,但可能正是你需要的。简言之,它使jOOQ在总是2次方长的条件下生成。这使得查询缓存更加容易

而不是这8个查询:

-原创的 从ID所在的作者中选择* 从ID所在的作者中选择*? 从ID所在的作者中选择*? 从ID所在的作者中选择*? 从ID位于的作者中选择*? 从ID所在的作者中选择*? 从ID所在的作者中选择*? 从ID位于的作者中选择*? 您将看到这4个查询,并且随着长度的增加而变得更好:

-填充 从ID所在的作者中选择* 从ID所在的作者中选择*? 从ID所在的作者中选择*? 从ID所在的作者中选择*? 从ID位于的作者中选择*? 从ID位于的作者中选择*? 从ID位于的作者中选择*? 从ID位于的作者中选择*? 我来这里是想建议在列表中填充。除此之外,正确的VisitListener解决方案将是侦听CONDITION_IN子句,记住某种堆栈中的信息,然后计算紧随其后的所有字段子句,直到CONDITION_IN子句再次结束。请记住,在in列表中可能还有一个表达式包含多个FIELD子句,而不是bind值


显然,Petr的建议要简单得多。

这是一个有趣的特性,但它不能解决查询计划优化的问题-我们需要优化2^n个查询计划。但是无论如何,谢谢你的建议!我不完全确定你所说的2^N是什么意思,因为它是另一种方式-不必缓存N个查询,只需缓存~log N个查询即可。最多31个绑定参数的查询只有6个变体。。。最多63个绑定参数只有7个变体。。。在运行时限制您的开发人员!仅绑定30个值似乎仍然过于人为。也就是说,你最了解你的领域,所以我很高兴你找到了一个适合你的解决方案。@lukaseder你这个鬼鬼祟祟的,鬼鬼祟祟的ninja@PetrJaneček:我不知道我的答案到底是如何被接受的,因为正确处理VisitListener是多么复杂:-这个解决方案只解决了查询缓存溢出的问题。但是,数据库管理员将被迫配置2^N个不同的查询计划,而不是一个谢谢你,现在我将尝试这个选项@Ацццццццццццццццццц!我的解决方案可能是正确的,但很难做到正确。。。此外,您在运行时(可能是在生产中)抛出异常,而不是允许选择几个长语句以标准化的OLOGN复杂性通过。正如Petr所解释的,在限制30个绑定变量的情况下,仍然会得到比使用标志更多的游标,在这种情况下,对于最多2^30的列表,只能得到30个游标!没那么难,至少我可以做我想做的事情:不是抛出异常,而是将此警告写入应用程序日志