有没有一种方法可以检查jOOQ中的查询绑定值?

时间:2018-07-11 16:51:04

标签: java sql jooq

对于包含IN条件且绑定参数很多的查询,我们遇到了问题,因为它们具有多种变体,并且很快会使查询缓存溢出。

如果要为in子句指定30个以上的绑定值,我想检入sql语句的condition子句并引发异常。

我可以使用VisitListener吗?

我可以使用org.jooq.VisitContext#clause查找innot in条件,但是我不能在没有反射的情况下检查org.jooq.impl.InCondition#values的大小。

现在我被迫做这样的事情:

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)?

2 个答案:

答案 0 :(得分:4)

另一个解决问题的方法通常是可以接受的,它是启用optional in-list padding in jOOQ

<settings xmlns="http://www.jooq.org/xsd/jooq-runtime-3.10.8.xsd">
  <inListPadding>true</inListPadding>
</settings>

这不完全是您想要的,但可能正是您需要的。简而言之,它使jOOQ生成{@ 1}}的条件,这些条件总是2的幂。这使得查询缓存更加容易。

代替此(8个查询):

IN

您将看到此信息(4个查询,并且随着长度的增加而变得越来越好):

-- Original
SELECT * FROM AUTHOR WHERE ID IN (?)
SELECT * FROM AUTHOR WHERE ID IN (?, ?)
SELECT * FROM AUTHOR WHERE ID IN (?, ?, ?)
SELECT * FROM AUTHOR WHERE ID IN (?, ?, ?, ?)
SELECT * FROM AUTHOR WHERE ID IN (?, ?, ?, ?, ?)
SELECT * FROM AUTHOR WHERE ID IN (?, ?, ?, ?, ?, ?)
SELECT * FROM AUTHOR WHERE ID IN (?, ?, ?, ?, ?, ?, ?)
SELECT * FROM AUTHOR WHERE ID IN (?, ?, ?, ?, ?, ?, ?, ?)

答案 1 :(得分:3)

我来这里是为了建议IN列表填充(as Petr did very nicely, in his answer)。除此之外,正确的VisitListener解决方案是侦听CONDITION_IN子句,记住某种堆栈中的信息,然后计算紧随其后的所有FIELD子句,直到CONDITION_IN子句再次结束。并且请记住,FIELD列表中可能还会有一个表达式(同样包含多个IN子句),而不是绑定值。

很显然,彼得的建议容易得多