PreparedStatement setString IN 传多个参数

今天在使用PreparedStatement进行预编译时,发现使用IN(String) 传入一个字符串一逗号为分隔符却失效,例如传入"a,b,c", 查询的不是"a" "b" "c"三个数据,而是"a,b,c"一个数据

 

SELECT d.* FROM TLK_列表_分页 d WHERE 1=1  AND ITEM_多行文本二 IN ( ?)

这条语句中的参数在使用PrepareStatement来预编译之后,是不可以传入一个拼接字符串的,比如

String test="'a','b','c'";
prepareStatement.setString(1,test);

想要达到执行效果

SELECT d.* FROM TLK_列表_分页 d WHERE 1=1  AND ITEM_多行文本二 IN ('a','b','c')

但是实际执行的sql语句是:

SELECT d.* FROM TLK_列表_分页 d WHERE 1=1  AND ITEM_多行文本二 IN ('a'',''b'',''c')

 

它不是查询 'a','b','c'这三个元素,而是查询'a,b,c,'这一个元素,所以达不到预期的效果

后来想过既然它插入的字符串是逗号两边少了单引号的话我就replace把 ","换成" ',' "

这样以后实际执行的sql语句是:

SELECT d.* FROM TLK_列表_分页 d WHERE 1=1  AND ITEM_多行文本二 IN ('a'',''b'',''c')

单引号变成了双引号,其实是sql防注入起了作用,它对单引号自动进行了转义 ' 变成了  '' 给单引号加多一个引号进行了转义。

于是只好使用笨办法,

String test里面有几个参数,那就有几个占位符 ?

就是当 String test="'a','b','c'"; 有两个逗号时,sql就应该是:

SELECT d.* FROM TLK_列表_分页 d WHERE 1=1  AND ITEM_多行文本二 IN ( ?,?,?)

这样就OK了。

添加占位符的代码如下:

        
                String temp = "IN ( ? ";
          //判断逗号出现的次数
int n = test.length() - test.replaceAll(",", "").length(); //根据参数的数量决定占位符的数量 if (sql.contains(temp)) {
            //循环添加占位符的次数要比逗号出现的次数多一次,即参数的数量。
for (int i = 0; i < n; i++) { sql = sql.replace(temp, temp + ",?"); temp = temp + ",?"; } } }

 这样为sql添加了对应的占位符后,如果不把test字符串进行切割,依然会报错,因为如果进行了添加占位符,你的sql变成了

SELECT d.* FROM TLK_列表_分页 d WHERE 1=1  AND ITEM_多行文本二 IN ( ?,?,?)

这样你就需要传入三个参数,仅仅是传入“a,b,c”的话是满足不了条件的。

     List<Object> sqlParameters;

 if (text.contains(",")) {
                int n = text.length() - text.replaceAll(",", "").length();
                //切割参数添加到sqlParameters
                for (int i = 0; i <= n; i++) {
                    String s = text.split(",")[i];
                    sqlParameters.add(i, text.split(",")[i]);
                }
                //添加完切割的参数后删除原来未切割的参数
                sqlParameters.remove(text);
            }

用List切割完以后就可以传入数据了。

 for (Object sqlParameter : sqlParameters) {
                parameterIndex++;
                if (sqlParameter instanceof String) {
                    preparedStatement.setString(parameterIndex, (String) sqlParameter);
                }

这个写法是可以满足PG数据库的

可以参考网站:https://blog.csdn.net/lismooth/article/details/76934980

posted @ 2019-05-08 13:51  Hiro-D  阅读(5330)  评论(0编辑  收藏  举报