面试官:使用JdbcTemplate in 语句你遇到过哪些坑?

最近,同事在空闲时间写了一个 Spring 的 demo,遇到了一个关于 JdbcTemplate 的小坑。今天我们一起来看看这个坑。

一般同事不喊我,一喊我准没好事。这次也不例外,他喊我并向我抛了一个异常:java.sql.SQLException: No value specified for parameter 3。并让我帮他检查代码,我基本上都是非常乐意的。因为帮助别人解决问题的过程中,我也能收获更多。不光是友谊,快乐和知识见识增长也是其中的一部分。

我看了他的代码,内容简化如下:

@Component("xttblogDao")
public class XttblogDaoImpl implements XttblogDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public List<Xttblog> selectByDynamicParams(List<Integer> idList, String name) {
        StringBuffer sql = new StringBuffer();
        sql.append("select * from xttblog where id in ( ");
        // 拼装SQL
        List<String> stringList = new ArrayList<>();
        for (int i = 0;i < idList.size();i++){
            stringList.add("?");
        }
        sql.append(String.join(",",stringList));
        sql.append(" ) and name = ?");
        System.err.println(sql.toString());
        return jdbcTemplate.query(sql.toString(),new XttblogMapper(),idList,name);
    }
}

然后测试上面的代码,发现最终报错:java.sql.SQLException: No value specified for parameter 3。

面试官:使用JdbcTemplate in 语句你遇到过哪些坑?
java.sql.SQLException: No value specified for parameter 3

一时间,我仔细看了看 SQL,没问题。然后把“ ) and name = ?”这部分去掉,也就是去掉最后一个查询参数。发现 OK 了,不报错了。

这是我又想到了 Spring 提供的另外一个类:NamedParameterJdbcTemplate。然后改造代码,使用 NamedParameterJdbcTemplate 查询一下试一试。

// 从容器中将dataSource这个对象注入进来
@Autowired
private DataSource dataSource;
@Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(){
    // 要构造NamedParameterJdbcTemplate对象需要依赖dataSource
    return new NamedParameterJdbcTemplate(dataSource);
}

同样的代码,换一个类就完全支持。

除此之外,JdbcTemplate 还有另外一个问题。比如,我们使用 SQL Server 的分页 top 时,同样无法使用 JdbcTemplate。因为 JdbcTemplate 只能将问号用于where语句中的参数。

关于 JDBC 的操作,Spring 提供了 3 个模板类供我们选择:

  • JdbcTemplate:提供按照索引参数传递,用 in 的时候要特别注意,推荐使用 NamedParameterJdbcTemplate。
  • NamedParameterJdbcTemplate:按照名字参数传递
  • SimpleJdbcTemplate:支持Java5特性,如自动装箱、泛型和可变参数列表等

JdbcTemplate 的处理逻辑是一个 ?一个参赛。而 in 往往我们可能只留了一个 ?。NamedParameterJdbcTemplate 在处理 sql 中 in 范围查询,会根据实际传入参数的 List 个数,做了一些修改,而原生的 JdbcTemplate 则不会这么做。

以上这些内容,希望能够帮助大家排除一些坑。

面试官:使用JdbcTemplate in 语句你遇到过哪些坑?

: » 面试官:使用JdbcTemplate in 语句你遇到过哪些坑?

原创文章,作者:sunnyman218,如若转载,请注明出处:https://blog.ytso.com/252088.html

(0)
上一篇 2022年5月4日
下一篇 2022年5月4日

相关推荐

发表回复

登录后才能评论