时隔三个多月,我终于想起我还有个博客,其实也不是忘了我这个博客,只是平时工作繁忙没时间去写博客,故今晚腾出时间来记录一下上次工作中遇到的一个问题,给园友们分享出来,以免入坑。

  上个星期在工作中使用JdbcTemplate执行了一个select * from table where id in (?,?,?) and name = ? 的SQL,这个SQL大家都明白什么意思吧,然后我得给这几个 "?" 赋值,没问题吧。可是在执行的时候给我报了一个异常:java.sql.SQLException: No value specified for parameter 3      纳尼?这就有点奇怪了,几个意思?是因为jdbcTemplate这个对象不支持括号内的问号和括号外的问号同时出现,什么意思呢?就是说  where id in (?) 是正确的  where name  = ? 也是正确的,但是  where id in (?) and name = ? 就不支持了;需要将 jdbcTemplate 对象换成 NamedParameterJdbcTemplate 即可,下面我会把代码贴出来,首先创建一个SpringBoot项目,将Web,MySQL,Jdbc,Lombok的依赖导入进去,然后我们开始撸代码:

  我们先来看一下数据库的数据:

  

  下面是建表语句,有需要的同志们可以复制过去:

CREATE TABLE `t_book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`isbn` varchar(255) DEFAULT NULL,
`publish` varchar(255) DEFAULT NULL,
`publisher` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

  实体类和表映射的RowMapper实现类的代码就不贴了,按照表字段去建一个就可以了,这一步跳过

  下面是controller和dao的代码:

@RestController
@RequestMapping("/api/v1/book")
public class BookRestController { @Resource
private ObjectMapper jsonMapper; // 这里为了方便就省略service层,直接将dao注入进来了
@Resource
private BookDAO bookDAO; @GetMapping("/list")
public JsonNode list(){
ObjectNode respJson = jsonMapper.createObjectNode();
List<Integer> idList = Arrays.asList(1, 2, 3);
String name = "mybatis从入门到精通";
List<TBook> bookList = bookDAO.selectByDynamicParams(idList, name);
return respJson.putPOJO("data",bookList);
}
}
@Component("bookDAO")
public class BookDAOImpl implements BookDAO { @Autowired
private JdbcTemplate jdbcTemplate; @Override
public List<TBook> selectByDynamicParams(List<Integer> idList, String name) {
StringBuffer sql = new StringBuffer();
sql.append("select * from t_book where id in ( ");
// 拼装?
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 BookMapper(),idList,name); }
}

  好了,执行一把,看一下结果吧,访问 localhost:8080/api/v1/book/list  ,控制台保如下错误:

  可以看出来,SQL语句的没有问题的,那么我们尝试换一种写法,使用 NamedParameterJdbcTemplate ,由于spring默认是加载jdbcTemplate的,所以NamedParameterJdbcTemplate 对象需要我们自己去配置,创建一个配置类或者直接在启动类配置也可以,启动类其实就是一个配置类,进行如下配置:

  

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

  dao层将NamedParameterJdbcTemplate 对象注入进来并执行SQL:

@Component("bookDAO")
public class BookDAOImpl implements BookDAO { @Autowired
private JdbcTemplate jdbcTemplate; @Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate; @Override
public List<TBook> selectByDynamicParams(List<Integer> idList, String name) {
String sql = "select * from t_book where id in (:idList) and name = :bookName";
// 集合中的key一定要与sql中定义的参数变量相同,这里的集合里的参数不需要进行手动处理,直接将集合作为一个参数对象传进去即可
Map<String,Object> params = new HashMap<>(2);
params.put("idList",idList);
params.put("bookName",name);
return namedParameterJdbcTemplate.query(sql,params,new BookMapper());
}
}

  这次再执行一把看一下结果:

  这次就执行成功了,控制台也没有报错,很舒服,我记得以前使用原生jdbc进行查询的时候当时使用的是sqlserver数据库,写了一条分页的SQL,当时也是有问号的,同样会报错,没想到spring的这个jdbc跟原生的jdbc一样坑,只能说技术这种东西学无止境呀。

  革命尚未成功,同志仍需努力!

JdbcTemplate的一次爬坑记录的更多相关文章

  1. mybatis-generator 详细配置及使用,爬坑记录

    mybatis-generator 详细配置及使用,爬坑记录 提示:如果不成功一定是项目路径和 数据库配置出问题,本篇基于 MySQL 8.0.13,调试没有问题. 如果失败,建议使用相同的项目结构, ...

  2. centos7安装Mysql爬坑记录

    centos7安装Mysql爬坑记录   查看是否已安装 使用下列命令查看是否已经安装过mysql/mariadb/PostgreSQL 如果未安装,不返回任何结果(ECS的centos镜像默认未安装 ...

  3. elasticsearch 单节点搭建与爬坑记录

    elasticsearch 单节点搭建与爬坑记录   prepare   虚拟机或者云服务器(这里用的是阿里云ECS) linux---centos7 安装完毕的jdk 相应的安装包(在https:/ ...

  4. 03、Swagger2和Springmvc整合详细记录(爬坑记录)

    时间 内容 备注 2018年6月18日 基本使用 spirngmvc整合swagger2 开始之前这个系列博文基本是,在项目的使用中一些模块的内容记录,但是后期逐渐优化,不单单是整合内容. swagg ...

  5. vuex2.0.0爬坑记录 -- mutations的第一个参数state不能解构

    今天在学习vuex的过程中,遇到了一个很困扰人的问题,最终利用vuex的状态快照工具logger解决了问题. 问题是这样的,我在子组件中使用了mapState()函数来将状态映射至子组件中,使子组件能 ...

  6. mac M1 php扩展 xlswriter 编译安装爬坑记录

    电脑配置 MacBook Pro(14英寸,2021年) 系统版本 macOS Monterey 12.4 芯片 Apple M1 Pro PHP环境 MAMP Pro Version 6.6.1 ( ...

  7. Vue开发爬坑记录

    1.使用eslint代码检查时,常见的的错误: 1.1 Expected indentation of 0 spaces but found 1 前面的空格个数不对.应该不能有空格. 1.2 Stri ...

  8. 开源中国/码云 README.md上传图片的爬坑记录

    整理代码,将电脑中长期没有用过的代码放到码云上托管,给项目录制gif动画,在写项目README.md时使用,结果在上传图片时一直出问题,现记录下最后解决方法: 1. 最初直接将录制好的图片放入到img ...

  9. webpack 4 入坑及爬坑记录

    一.安装 在本机安装好nodejs的基础上,window操作系统,cmd打开控制台,添加到创建的文件夹下 npm init //初始化npm npm install webpack --save-de ...

随机推荐

  1. 多个PVSS数据点属性读写的优化处理

    注:本译文出自15多年前,尚未用最新软硬件平台进行重新测试,只提供方法论层面的参考,具体性能指标不具备参考意义. 多个PVSS数据点属性读写的优化处理 本文档概述了测试三种读取和写入多个PVSS数据点 ...

  2. bs4库学习

    # -*- coding:utf-8 -*- import bs4 import requests def tags_val(tag, key='', index=0): ''' tag指HTML元素 ...

  3. itunes 备份导致C盘空间不足问题解决办法

    首先,itunes备份的默认路径是 C:\users\你的用户名\Appdata\Roaming\Apple computer 备份的主要存放文件在C:\Users\David_lu\AppData\ ...

  4. springboot添加多数据源连接池并配置Mybatis

    springboot添加多数据源连接池并配置Mybatis 转载请注明出处:https://www.cnblogs.com/funnyzpc/p/9190226.html May 12, 2018  ...

  5. 平时作业六 java

    编写一个Java应用程序,使用Java的输入输出流技术将Input.txt的内容(Input.txt为文本文件)逐行读出,每读出一行就顺序为其添加行号(从1开始,逐行递增),并写入到另一个文本文件Ou ...

  6. selenium 不同版本Driver

    selenium进行UI自动化测试需要Driver支持,不同的浏览器需要不同的Driver,之前使用的Driver可以正常运行,但是总会报一些莫名的问题,经过查找,原来IE的Driver需要与sele ...

  7. BZOJ1757 : Apple 偷苹果

    设$f0[i][j][x][y][S]$表示盗贼位于$(i,j)$,守卫位于$(x,y)$,每棵苹果树苹果数量为$S$,盗贼先手时盗贼还能偷多少苹果. 设$f1[i][j][x][y][S]$表示盗贼 ...

  8. python 错误记录

    class Func: d = dict() def __setitem__(self, key, value): # xxx object does not support item assignm ...

  9. java数组和集合的相互转换

    由于在学习过程中经常碰到这么一个问题,就是java中几种装数据的容器之间的转换,所以写了这篇随笔专门来总结这些转换方法. 数组转集合: 1.遍历,最常用的方法,但是过程会繁琐一点 int arrs[] ...

  10. 2018申请淘宝客AppKey

    1.www.alimama.com 申请账号进入后2.进入我的联盟,按下面的步骤 完成以后等待网站审核. 3.审核完成后 按以下的图,申请进入开放平台或得appkey 4.最后就可以进入开放平台申请看 ...