使用绑定变量的jooq查询

Posted

技术标签:

【中文标题】使用绑定变量的jooq查询【英文标题】:jooq query using bind variables 【发布时间】:2021-03-14 15:16:31 【问题描述】:

我使用绑定变量使用以下代码进行批量更新

`var balanceUpdate = dslContext.batch(
                dslContext.update(BALANCE)
                .set(BALANCE.BALANCE, (BigDecimal) null)            
                .where(BALANCE.ID.eq((String) null)));
        balances.forEach(balance -> 
            balanceUpdate.bind(
                    balance.getAmount()
                    balance.Id);
        );
        int[] execute = balanceUpdate.execute();

`

上面的代码运行良好,但现在我想使用带有参数数组的绑定,例如

var balanceUpdate = dslContext.batch(
                    dslContext.update(BALANCE)
                            .set(BALANCE.BALANCE, (BigDecimal) null)
                            .where(BALANCE.ID.eq((String) null)));
           
            var arguments = balances.stream()
                    .map(balance -> 
                                new Object[] 
                                 balance.getAmount(), 
                                 balance.Id
            ).collect(Collectors.toList());
            
            int[] execute = balanceUpdate.bind(arguments).execute();

我得到异常

java.lang.ArrayStoreException: arraycopy: element type mismatch: can not cast one of the elements of java.lang.Object[] to the type of the destination array, java.math.BigDecimal
    at org.jooq_3.14.4.ORACLE12C.debug(Unknown Source)
    at java.base/java.util.Arrays.copyOf(Arrays.java:3722)
    at org.jooq.tools.Convert.convertArray(Convert.java:357)
    at org.jooq.tools.Convert.convertArray(Convert.java:345)
    at org.jooq.tools.Convert$ConvertAll.from(Convert.java:603)
    at org.jooq.tools.Convert.convert0(Convert.java:392)
    at org.jooq.tools.Convert.convert(Convert.java:384)
    at org.jooq.tools.Convert.convert(Convert.java:458)
    at org.jooq.tools.Convert.convertArray(Convert.java:363)
    at org.jooq.tools.Convert.convertArray(Convert.java:345)
    at org.jooq.tools.Convert$ConvertAll.from(Convert.java:614)
    at org.jooq.tools.Convert.convert0(Convert.java:392)
    at org.jooq.tools.Convert.convert(Convert.java:384)
    at org.jooq.tools.Convert.convert(Convert.java:458)
    at org.jooq.impl.AbstractDataType.convert(AbstractDataType.java:534)
    at org.jooq.impl.DefaultDataType.convert(DefaultDataType.java:86)
    at org.jooq.impl.DSL.val(DSL.java:24409)
    at org.jooq.impl.DSL.val(DSL.java:24377)
    at org.jooq.impl.Tools.field(Tools.java:1794)
    at org.jooq.impl.Tools.fields(Tools.java:1865)
    at org.jooq.impl.BatchSingle.executePrepared(BatchSingle.java:226)
    at org.jooq.impl.BatchSingle.execute(BatchSingle.java:170)

根据docs 它应该可以工作吗?至少它在使用 jdbc 时无需显式转换即可工作。有没有办法让它只发送一次绑定变量而不是像第一个示例中那样多次发送?

【问题讨论】:

【参考方案1】:

我认为您调用了错误的 BatchBindStep.bind(Object...) 方法,或者至少不是您期望的方式。当前没有接受List<Object[]> 类型集合的重载。所以,你应该做的是为你的绑定变量集创建一个Object[][] 类型:

Object[][] arguments = balances
    .stream()
    .map(balance -> new Object[] 
        balance.getAmount(), 
        balance.Id
    ).toArray();

【讨论】:

以上是关于使用绑定变量的jooq查询的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle 11g 中转换动态查询以使用绑定变量

jOOQ 不使用自定义数据绑定

在 java8 中使用绑定变量的 Cassandra 选择查询

什么是 RowMapper、ResultSetExtractor、绑定变量和查询类型?

教义,子查询,无效参数号:绑定变量的数量与标记的数量不匹配

雪花 - 使用绑定变量