SpringJDBC:Parameter index out of range (1 > number of parameters, which is 0).


数据库错误:Parameter index out of range (1 > number of parameters, which is 0).

错误发生原因其实很简单,就是当设置参数时,没有相应的问号与之匹配(或者根本就没有?号)

与sql语句有关的原因如下:
第一种:?号被单引号包围。

(正确的应该是?号的两边没有单引号包围才对)
(如setString(1,“slkdjfkd”);时sql语句为:insert into table1 (c1,c2) values (’?’,’?’))。
此时?会被作为参数传入,而不会再传入 setString里面的值。
第二种: sql语句中没有?号,在后面用到了set语句。

(如:select * from table);此时无需传值。传值就会出错。
第三种:初学者很常见的错误:?—? 写成了中文的问号导致报错

这两个问号是不同了,因为一个是中文,一个是英文,如果在sql语句中写入的是中文,将无法识别。

以上是在网上找到的问题的解答,经过分析我程序的问题属性第二种。我实际上使用SQL语句是SELECT COUNT(id) FROM app_role LIMIT 20 OFFSET 0,这里面没有占位符,但我却传递了参数,参数的类型是Map。实际上这个Map中是没有内容的即Map.size()=0。

我的问题来了,我必须使用Map传递参数,在没有参数时Map的size=0,这种情况该如何处理呢?

这就是JdbcTemplate和NamedParameterJdbcTemplate类在使用上的差别。

首先JdbcTemplate中方法queryForObject:

T queryForObject(String sql, RowMapper rowMapper, @Nullable Object... args) throws DataAccessException;

注意它的次序,它的参数是最后一个,如果在sql语句中没有?占位符,那么参数args必须是空的,而我却传递了一个Map类型,类型和个数都不适合,于是发生了错误

在使用NamedParameterJdbcTemplate的queryForObject方法:

public T queryForObject(String sql, Map paramMap, Class requiredType) throws DataAccessException

注意SQL语句中使用命名参数是通过Map传递的,如果sql中没有命名参数则不需要paramMap中的参数进行替换,这真是一个好的用法,因此当你需要传递参数时参数个数不需要自己判断。于是这个错误使用NamedParameterJdbcTemplate的queryForObject方法就解决了。