JdbcTemplate的一次爬坑记录
时隔三个多月,我终于想起我还有个博客,其实也不是忘了我这个博客,只是平时工作繁忙没时间去写博客,故今晚腾出时间来记录一下上次工作中遇到的一个问题,给园友们分享出来,以免入坑。
上个星期在工作中使用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的一次爬坑记录的更多相关文章
- mybatis-generator 详细配置及使用,爬坑记录
mybatis-generator 详细配置及使用,爬坑记录 提示:如果不成功一定是项目路径和 数据库配置出问题,本篇基于 MySQL 8.0.13,调试没有问题. 如果失败,建议使用相同的项目结构, ...
- centos7安装Mysql爬坑记录
centos7安装Mysql爬坑记录 查看是否已安装 使用下列命令查看是否已经安装过mysql/mariadb/PostgreSQL 如果未安装,不返回任何结果(ECS的centos镜像默认未安装 ...
- elasticsearch 单节点搭建与爬坑记录
elasticsearch 单节点搭建与爬坑记录 prepare 虚拟机或者云服务器(这里用的是阿里云ECS) linux---centos7 安装完毕的jdk 相应的安装包(在https:/ ...
- 03、Swagger2和Springmvc整合详细记录(爬坑记录)
时间 内容 备注 2018年6月18日 基本使用 spirngmvc整合swagger2 开始之前这个系列博文基本是,在项目的使用中一些模块的内容记录,但是后期逐渐优化,不单单是整合内容. swagg ...
- vuex2.0.0爬坑记录 -- mutations的第一个参数state不能解构
今天在学习vuex的过程中,遇到了一个很困扰人的问题,最终利用vuex的状态快照工具logger解决了问题. 问题是这样的,我在子组件中使用了mapState()函数来将状态映射至子组件中,使子组件能 ...
- mac M1 php扩展 xlswriter 编译安装爬坑记录
电脑配置 MacBook Pro(14英寸,2021年) 系统版本 macOS Monterey 12.4 芯片 Apple M1 Pro PHP环境 MAMP Pro Version 6.6.1 ( ...
- Vue开发爬坑记录
1.使用eslint代码检查时,常见的的错误: 1.1 Expected indentation of 0 spaces but found 1 前面的空格个数不对.应该不能有空格. 1.2 Stri ...
- 开源中国/码云 README.md上传图片的爬坑记录
整理代码,将电脑中长期没有用过的代码放到码云上托管,给项目录制gif动画,在写项目README.md时使用,结果在上传图片时一直出问题,现记录下最后解决方法: 1. 最初直接将录制好的图片放入到img ...
- webpack 4 入坑及爬坑记录
一.安装 在本机安装好nodejs的基础上,window操作系统,cmd打开控制台,添加到创建的文件夹下 npm init //初始化npm npm install webpack --save-de ...
随机推荐
- 19.3.5日,报关于表单验证和ui-router
今天完成的事情: (1)学习angularJS表单验证 可以验证的内容<input type="text" minlength="2" maxlength ...
- 06flask_migrate
1,flask-migrate介绍: 因为采用db.create_all()在后期修改字段的时候不会自动的映射到数据库中,必须删去表,然后运行 db.create_all()才会重新映射,这样不符合我 ...
- sqlzoo:using group by and having
For each continent show the number of countries: SELECT continent, COUNT(name) FROM world GROUP BY c ...
- BZOJ5335 : [TJOI2018]智力竞赛
二分答案,转化成求最少的路径,覆盖住所有权值$\leq mid$的点. 建立二分图,若$i$的后继为$j$,则连边$i\rightarrow j$,求出最大匹配,则点数减去最大匹配数即为最少需要的路径 ...
- java用jsoup解析HTML
步骤 1获取document对象 //方法一 Document doc = Jsoup.connect(网址).get() //方法二 Document doc = Jsoup.parse(html字 ...
- angular.isUndefined()
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- JdbcTemplate实体映射
JdbcTemplate实体映射 如果你需要使用JdbcTemplate将查询的数据映射成Java POJO,那么这篇文章适合你. 一个例子入门 下面是一个将表中一行记录映射成Map的例子,也是Jdb ...
- Spring Cloud 组件 —— eureka
官方文档,Spring Cloud 对其封装,Spring Cloud eureka 文档
- Consider defining a bean named 'entityManagerFactory' in your configuration解决办法
错误信息: *************************** APPLICATION FAILED TO START *************************** Descriptio ...
- SQL Server 恢复数据库至指定时间点
发生数据库误删的情况下,及时恢复数据到误操作前的状态 工具/原料 SQL Server Management Studio 数据库完整备份及日志备份 必备条件 1 数据库右键属性,在选项中查看 ...