背景
上两篇文章<模板方法模式与JdbcTemplate>和<新手坑揭秘:JdbcTemplate的queryForList>用的示例都是没有参数的,在有参数的时候JdbcTemplate该如何使用呢?
JdbcTemplate支持带参数的sql执行,内部使用SimplePreparedStatementCreator封装了PreparedStatement,使用newArgPreparedStatementSetter来封装参数。
另外JdbcTemplate通过Object[]数组来给PreparedStatement来设置参数,这容易造成混乱,NamedParameterJdbcTemplate支持通过名称的方式来传递参数给PreparedStatement。
JdbcTemplate实例和NamedParameterJdbcTemplate实例
前期准备
表创建
CREATE TABLE `student1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) DEFAULT NULL,
`last_name` varchar(100) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
插入数据
在spring-jdbc项目中增加mysql的依赖:
JdbcTemplate实例
定义JavaBean
定义映射对象
配置DataSource和JdbcTemplate
测试程序
运行程序结果:
5,www,baidu.com,23
7,www,baidu.com,23
8,www,baidu.com,23
从上面的测试程序看到,
1.传入的参数是以Object[]数组形式传入的,如果参数比较多,容易搞混乱
2.在java中我们更习惯使用参数名称来做这件事,spring做了一些工作:NamedParameterJdbcTemplate
NamedParameterJdbcTemplate实例
测试程序
运行结果
深入原理5,www,baidu.com,23
7,www,baidu.com,23
8,www,baidu.com,23
JdbcTemplate
关键点:query()方法
第一步:将参数Object[]数组封装成ArgumentPreparedStatementSetter
@Override
@Nullable
public <T> T query(String sql, @Nullable Object[] args, ResultSetExtractor<T> rse) throws DataAccessException {
return query(sql, newArgPreparedStatementSetter(args), rse);
}
query()方法调用ArgumentPreparedStatementSetter的方法setValues()设置参数
第二步:封装sql到PrepareStatement到SimplePreparedStatementCreator中,其执行方法为:
createPreparedStatement在JdbcTemplate.java#execute方法中调用
第三步:使用RowMapper实现类将ResultSet结果转换成javaBean
NamedParameterJdbcTemplate
第一步将Map参数封装为MapSqlParameterSource
第二步将sql和参数封装到PreparedStatementCreator
第三步:调用JdbcTemplate的query()方法
从JdbcTemplate和NamedParameterJdbcTemplate来看,针对jdbc要用的三个要素:sql,参数param,ResultSet结果转换分别进行了封装。
-
sql可以封装成SimplePreparedStatementCreator或者PreparedStatementCreator的实现类
-
参数param可以封装成ArgumentPreparedStatementSetter或者PreparedStatementCreator实现类
-
ResultSet结果转换可以封装成RowMapper实现类或者RowCallbackHandler实现类