mysql不支持PreparedStatement.setArray()的解决方案

当MySQL的PreparedStatement不支持通过setArray传递数组作为IN条件时,可以使用FIND_IN_SET函数来替代。此方法将数组参数转换为逗号分隔的字符串形式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查询中有in条件的时候mysql数据库不支持通过PreparedStatement.setArray()传递数组的方式设置参数,如:
PreparedStatement pstmt = conn.prepareStatement(“select * from table1 where id in (?)”);
Array array = conn.createArrayOf(“VARCHAR”, new Object[]{“1”, “2”,”3”});
pstmt.setArray(1, array);
ResultSet rs = pstmt.executeQuery();
运行后会报SQLFeatureNotSupportedException错误。

解决方案:
使用FIND_IN_SET函数代替in条件,上述语句改成:
PreparedStatement pstmt = conn.prepareStatement(“select * from table1 where FIND_IN_SET(id, ? )”);
pstmt.setString(1, “1,2,3”);
ResultSet rs = pstmt.executeQuery();
即:将数组中的参数拼接成一个字符串,用,隔开。

mysql手册中find_in_set函数的语法:

FIND_IN_SET(str,strlist)

假如字符串str 在由N 子链组成的字符串列表strlist 中,则返回值的范围在 1 到 N 之间。
一个字符串列表就是一个由一些被‘,’符号分开的子链组成的字符串。如果第一个参数是一个常数字符串,而第二个是type SET列,则 FIND_IN_SET() 函数被优化,使用比特计算。
如果str不在strlist 或strlist 为空字符串,则返回值为 0 。如任意一个参数为NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。

mysql> SELECT FIND_IN_SET(‘b’,’a,b,c,d’);

-> 2 因为b 在strlist集合中放在2的位置 从1开始


select FIND_IN_SET(‘1’,’1’); 返回 就是1 这时候的strlist集合有点特殊 只有一个字符串 其实就是要求前一个字符串 一定要在后一个字符串集合中 才返回 大于0的数

select FIND_IN_SET(‘2’,’1,2’);返回2

select FIND_IN_SET(‘6’,’1’); 返回0


注意:
select * from treenodes where FIND_IN_SET(id,’1,2,3,4,5’);
使用find_in_set函数一次返回多条记录

id 是一个表的字段 然后每条记录分别是id等于1,2,3,4,5的时候
有点类似in (集合)
select * from treenodes where id in (1,2,3,4,5);

``` package jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Collection; /** * 修改数据 */ public class JDBCDemo9 { public static void main(String[] args) { try(Connection connection = DBUtil.getConnection();) { /** * JDBC中事物是自动提交的,意味着我们每执行一句DML语句,都会自动提交 * 如果我们需要自行控制事物,需要设置不自动提交 */ connection.setAutoCommit(false); String sql="UPDATE user "+ "SET password=? ,+nickname=? ,age=? "+ "WHERE id=? "; PreparedStatement ps= connection.prepareStatement(sql); ps.setString(1, "184754"); ps.setString(2, "小明"); ps.setInt(3, 18); ps.setInt(4, 3); int num=ps.executeUpdate(); System.out.println(num>0?"修改成功":"修改失败"); connection.commit(); System.out.println("修改成功!"); connection.rollback(); System.out.println("修改失败!,修改回滚!"); } catch (SQLException e) { e.printStackTrace(); } } }```"C:\Program Files\Java\jdk-17\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2024.3.4\lib\idea_rt.jar=55161" -Dfile.encoding=UTF-8 -classpath D:\java-student\JSD2502_SSM\JDBC\target\classes;C:\Users\2003q\.m2\repository\mysql\mysql-connector-java\8.0.15\mysql-connector-java-8.0.15.jar;C:\Users\2003q\.m2\repository\com\google\protobuf\protobuf-java\3.6.1\protobuf-java-3.6.1.jar;C:\Users\2003q\.m2\repository\com\alibaba\druid\1.1.21\druid-1.1.21.jar jdbc.JDBCDemo9 3月 26, 2025 9:20:49 上午 com.alibaba.druid.pool.DruidDataSource info 信息: {dataSource-1} inited java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '+nickname='小明' ,age=18 WHERE id=3' at line 1 at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:970) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1109) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1057) at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1377) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1042) at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeUpdate(DruidPooledPreparedStatement.java:255) at jdbc.JDBCDemo9.main(JDBCDemo9.java:28)
03-27
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值