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

  上个星期在工作中使用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. 英语口语练习系列-C41-食物词汇-鹊桥仙

    词汇 1, rice [raɪs] n. 稻:米饭 vt. 把-捣成米糊状 Rice: 米饭 | 大米 | 稻 2, bread [bred] n. 面包:生计 vt. 在-上洒面包屑 Bread: ...

  2. MyBatis(五)select返回list数据

    (1)接口中编写方法 public List<Emp> getEmps(String lastName); (2)编写Mapper文件 <select id="getEmp ...

  3. 再回首数据结构—数组(Golang实现)

    数组为线性数据结构,通常编程语言都有自带了数组数据类型结构,数组存放的是有个相同数据类型的数据集: 为什么称数组为线性数据结构:因为数组在内存中是连续存储的数据结构,数组中每个元素最多只有左右两个方向 ...

  4. MUI消息推送

    一.push通过H5+实现 简单实现方式:通过轮询服务器是否有新消息推送过来 mui.plusReady(function() { plus.navigator.closeSplashscreen() ...

  5. 自主学习python文本进度条及π的计算

    经过自己一段时间的学习,已经略有收获了!在整个过程的进行中,在我逐渐通过看书,看案例,做题积累了一些编程python的经验以后,我发现我渐渐爱上了python,爱上了编程! 接下来,当然是又一些有趣的 ...

  6. 微信测试号开发入门配置问题java

    这个测试号配置弄了好几天了,入了无数坑,终于解决了...辛苦我了,手动安慰一下自己.. 为了萌新们以后不要再浪费时间绕半天做无用功.看看楼楼的艰苦历程吧. 此教程针对没有云服务器,没有自己的域名的.没 ...

  7. Python练手例子(13)

    73.反向输出一个链表. #python3.7 if __name__ == '__main__': ptr = [] for i in range(5): num = int(input('Plea ...

  8. DCOS实践分享(5):Open DCOS深入分析

    2016/05/18(三) 09:30 OpenDC/OS研討會暨工作坊 指導單位:經濟部.科技部 主辦單位:工業技術研究院.Linker Networks 協辦單位:Microsoft.資通訊產業聯 ...

  9. 位运算-出现k次与出现一次

    题目:数组中arr只有一个数出现了1次,其他的数都出现了k次,请输出这个只出现了一次的数. 思路:这道题目要求使用位运算实现,如果采用数据结构Map就会简单很多.解此题前先了解不进位加法的思想,比如两 ...

  10. Batch入门教程丨第一章:部署与Hello World!(上)

    Batch入门教程 在本教程中,您将了解并学习与Windows Batch有关的知识和编程方法,用以解决在日常生活中所遇到的简单问题,或者利用Windows Batch建立一个最初级的编程思维方式. ...