在Dropwizard JDBI中执行PostgreSQL数组&&运算符查询报错求助
解决Dropwizard JDBI + PostgreSQL数组交集查询的问题
嘿,我来帮你搞定这个问题~看报错信息就能揪出问题根源:你用的@BindIn注解会把List<Integer>拆成多个独立的参数,比如你传了[2,3],生成的SQL就变成了SELECT ARRAY[1,2] && ?,?。这时候PostgreSQL会把右边的?当成单个integer类型,自然找不到integer[] && integer这个运算符,所以才会抛出那个错误。
下面给你几个靠谱的解决办法:
方法1:用@Bind替代@BindIn(推荐)
Dropwizard JDBI默认支持把Java数组/List映射成PostgreSQL的数组类型,所以直接用@Bind注解就行,不用拆分成多个参数:
@SqlQuery("SELECT ARRAY[1,2,3,4] && :input_array") public abstract Boolean query(@Bind("input_array") Integer[] inputArray);
调用的时候把List转成数组就行:
List<Integer> list = new ArrayList<>(); list.add(2); list.add(3); query(list.toArray(new Integer[0]));
如果想直接绑定List,你也可以试试下面的写法(Dropwizard 1.1.0的JDBI版本应该支持自动映射):
@SqlQuery("SELECT ARRAY[1,2,3,4] && :input_array") public abstract Boolean query(@Bind("input_array") List<Integer> list);
方法2:手动构造PostgreSQL数组字符串(应急用)
要是你暂时没法用数组映射,也可以手动把List转换成PostgreSQL的数组格式字符串,再配合类型转换。不过这个方法有SQL注入风险,尽量少用:
@SqlQuery("SELECT ARRAY[1,2,3,4] && CAST(:input_array AS integer[])") public abstract Boolean query(@Bind("input_array") String inputArrayStr);
调用的时候构造符合PostgreSQL格式的字符串:
List<Integer> list = new ArrayList<>(); list.add(2); list.add(3); String arrayStr = "{" + String.join(",", list.stream().map(String::valueOf).toArray(String[]::new)) + "}"; query(arrayStr);
方法3:用any函数实现等价逻辑
另一种思路是用PostgreSQL的any函数来判断数组是否有交集,逻辑和&&运算符完全一致:
@SqlQuery("SELECT EXISTS (SELECT 1 FROM unnest(ARRAY[1,2,3,4]) a WHERE a = ANY(:input_array))") public abstract Boolean query(@Bind("input_array") Integer[] inputArray);
最后提个小建议:把方法的返回值从Object改成Boolean,这样类型更明确,后续处理也更方便~
内容的提问来源于stack exchange,提问作者Vijay Shegokar
相关产品推荐
相关产品推荐

