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一样坑,只能说技术这种东西学无止境呀。
革命尚未成功,同志仍需努力!
上一篇: 对颜值没什么概念
下一篇: php中对2个数组相加的函数