以下MySQL查询是等效的:

select * from TableA where (column1, column2) in ( ('name1', 60), ('name2', 65) )
select * from TableA where (column1='name1' and column2=60) or (column1='name2' and column2=65)

然而,行构造函数表单(即第一个示例)的强大之处在于,您可以使用它来处理查询任意长度的值对列表.如果没有它,就必须编写动态sql,这是一种安全风险.使用第一种形式可以避免这个棘手的问题.

然而,如何在JDBC中使用准备好的语句来表示这一点?例如:

Connection connection = ...
PreparedStatement smt = connection.preparedStatement("select * from TableA where (column1,column2) in ?");
smt.setObject(1, whatDataTypeGoesHere );
smt.execute();

我已经研究了setArray,但是如何在数组的值中表示column1column2个值呢?我想知道SQLData接口是否可以作为管道.但是读了这些文件,我看不出这是怎么回事.

推荐答案

据我所知,MySQL在Connector/J中的实现不支持setArray().它抛出java.sql.SQLFeatureNotSupportedException.

即使它确实实现了setArray(),我也没有使用过它,也没有看到任何文档显示将该方法用于行构造函数而不是标量类型的示例.这可能是因为它不是适合你的任务的正确解决方案.

我想你必须写一个字符串生成器来做你想做的事情.可以编写构建SQL查询的代码.只有在SQL查询字符串中使用不受信任的内容时,才会有SQL注入风险.如果你只使用严格受你自己代码控制的内容,你可以确保它不危险.

例如,在下面的示例中,插入到SQL字符串中的内容仅基于调用代码中的字符串文本.不使用来自不受信任来源的内容.

String placeHolders = String.join(",",
  Collections.nCopies(params.size(), "(?, ?)"));
String sql = "select * from TableA where (column1, column2) in ( (" 
  + placeHolders + ")";

(假设params是一个对象数组,从中可以获得与column1和column2对应的值.)

这将产生一个SQL字符串,如

select * from TableA where (column1, column2) in ((?, ?), (?, ?), (?, ?), ...)

然后你必须在你想要绑定的参数数组上循环,每个循环设置setString()两次.

Java相关问答推荐

如果一个子类没有构造函数,超类也没有构造函数,那么为什么我可以构造子类的实例呢?

为什么BasicComboBoxRenderer在文本不存在或文本为空的情况下设置两次文本?

Jlink选项&-strie-ative-Commands";的作用是什么?

如何在带有Micronaut的YAML中使用包含特殊字符的字符串作为键

SpringBootreact 式Web应用程序的Spring Cloud Configer服务器中的资源控制器损坏

在JavaFX项目中注册组合框的控件FX验证器时,模块系统出错

使用GridBagLayout正确渲染

安装Java Jar应用程序的Install4j遇到ClassNotFoundException的运行时错误

Spring和可编辑";where";@Query

将java.util.Date转换为OffsetDateTime

Java泛型类方法的静态返回类型是否被类型擦除?

Java 11 HttpCookie.parse在解析包含JSON的Cookie时引发IlLegalArgumentException

视图被推出线性布局-Android

Java中的发布/订阅-Long Live和Short Live Publisher,哪种方法是正确的?

为什么创建Java动态代理需要接口参数

Java 17与Java 8双重表示法

Java中的一个错误';s stdlib SocksSocketImpl?

Xml Reader 将 BMP 外部的字符解析为代理项对,这会导致无效的 xml

元音变音字符:如何在 Java 中将Á<0x9c>转换为Ü?

如何使用 JDBC 更改 Postgres Enum 类型