该文章基于《Spring源码深度解析》撰写,感谢郝佳老师的奉献
JDBC模块
UPDATE
方法一
public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException {
return this.update(sql, this.newArgTypePreparedStatementSetter(args, argTypes));
}
方法二
public int update(String sql, PreparedStatementSetter pss) throws DataAccessException {
return this.update((PreparedStatementCreator)(new JdbcTemplate.SimplePreparedStatementCreator(sql)), (PreparedStatementSetter)pss);
}
可以看到进入方法一update方法后Spring先使用了ArgTypePreparedStatmentSetter对参数进行类型封装之后再进入方法二。方法二中再通过execute方法执行核心的运行,在execute方法中达成了这样几个目的:
(1)获取数据库的连接
(2)应用用户设定的参数类型(设置的抓取行数,以及可以包含的最大行数)
(3)调用回调函数(PreparedStatementCallback的doInPreparedStatement方法)
(4)警告处理(使用了SQLWarning)
(5)资源释放(考虑到存在事务的情况,如果当前线程存在事务,那么就说明当前线程存在公用数据库连接,通过使用ConnectionHolder的released方法将连接数减一,而不是真正的释放连接)
接下来讨论回调函数,回调函数为PreparedStatementCallback的doInPreparedStatement方法,在不同的操作中具有不同的实现,在这个函数中也是Spring提供封装的一个方法点,通过便利每个参数以作类型匹配和转换就可以达到简化的目的。
QUERY
query整体与update差不多,只不过没有了参数的解析,但是多了一步将ResultSet转换为POJO的步骤(借助于RowMapper实现类的帮助)
当sql语句不带”?“查询符号时,实际上execute使用的是Statement,而带上”?“查询符号的一般为PreparedStatement,PreparedStatement是Statement的子类。