Java基础、中级、高级、架构面试资料

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

JAVA herman 4190浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

最近,同事在空闲时间写了一个 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。

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 则不会这么做。

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

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » 面试官:使用JdbcTemplate in 语句你遇到过哪些坑?