你好,
首先,感谢您提供这么棒的图书馆。
我遇到的错误如下:
绑定空列表
没有为 java.util.List 类型的“[]”注册参数工厂
你能提供更多的上下文吗? 你在执行什么 SQL? 哪个数据库供应商?
嗨@qualidafial ,
查询: select * from invoice where invoice.id IN :ids
数据库供应商:SQL Server 2017
好的,现在说得通了。
JDBC 在处理数组时有点奇怪——您必须知道数据库供应商使用的数据类型名称。 为了帮助 Jdbi 连接点,您必须为每个 Java 类名注册数组元素类型名称:
Jdbi jdbi = Jdbi.create(...);
...
jdbi.registerArrayType(int.class, "integer");
jdbi.registerArrayType(Integer.class, "integer");
话虽如此,我们可以改进我们的异常消息,为用户指明正确的方向。
@qualidafial兄弟,这是一流的,非常感谢!
:+1: 提醒一下,如果您能指点我一些文档,我们可以向 Jdbi 添加一个 SQL Server 插件,以便我知道驱动程序支持哪些自定义数据类型,以及 Java 类型和 JDBC 数据类型之间的映射关系名称。
@qualidafial仅供参考,显然 SQL Server JDBC 驱动程序不支持带有准备好的 SqlArray 的 IN 语句
您也可以使用@BindList
:
@SqlQuery("select * from invoice where invoice.id IN (<ids>)")
Set<Invoice> getInvoices(@BindList("ids") List<Integer> ids);
请注意,不同的数据库供应商可能会对逗号分隔的WHERE column IN (a, b, c, ...)
子句中允许的项目数进行限制。
显然 SQL Server 只支持单值参数,所以我手动创建了数组,但是这对于 String 数组是不安全的,并且会引入 SQL 注入。
default List<LotInvoiceRef> getInvoices(List<Long> invoiceIds) {
final List<LotInvoiceRef> lotInvoiceRefs = invoiceIds.stream()
.map(String::valueOf)
.reduce((a, b) -> a + "," + b)
.map(this::getAllInvoiceRefs)
.orElse(new ArrayList<>());
return lotInvoiceRefs;
}
@georgerb请看我的最后一条评论,它可以防止 SQL 注入
@qualidafial我喜欢@BindList方法,但我需要一种方法来允许@BindList明确禁止的参数的空列表。
@qualidafial nvm,快速挖掘注释,我使用了这个: @BindList(value = "invoiceIds", onEmpty = BindList.EmptyHandling.NULL)
,它完美地工作
再次,这是一流的。 有没有办法让我们做出贡献? 至少可以帮助你们处理文档。
谢谢,你真好。 我们 :heart: 拉取请求!
仅从这次谈话中,我就总结出三个可能的改进:
@BindList
开发人员指南部分(可能还有@DefineList
而我们在此期间)。如果您愿意提交针对上述每个问题的单独问题。 然后我们可以关闭这个并单独跟踪每个。
如果您有一些改进 Jdbi 的想法并希望与之一起运行,请执行! JPA、Kotlin 和 Vavr 插件,以及 Core 和 SQL Object 的许多元素都是 Jdbi 用户提交的。
@qualidafial完成。 第993章
谢谢! 关闭此问题以支持 #993
最有用的评论
好的,现在说得通了。
JDBC 在处理数组时有点奇怪——您必须知道数据库供应商使用的数据类型名称。 为了帮助 Jdbi 连接点,您必须为每个 Java 类名注册数组元素类型名称: