Spring 连接数据库程序实现( JDBC )
创建数据表结构
创建对应数据表的 PO
创建表与实体间的映射
创建数据操作接口
创建数据操作接口实现类
创建 Spring 配置文件
测试
save/update 功能的实现
首先以保存实体类为例进行代码跟踪
进入 jdbcTemplate中的 update 方法。
进入 update 方法后, Spring 并不是急于进入核心处理操作,而是先做足准备工作,使用
ArgTypePreparedStatementSetter 对参数与参数类型进行封装 ,同时又使用 SimplePreparedStatement
Creator 对 SQL 语句进行封装
经过了数据封装后便可以进入了核心的数据处理代码了
基础方法 execute
execute 作为数据库操作的核心入口, 将大多数数据库操作相同的步骤统一封装 ,而将个性
化的操作使用参数 PreparedStatementCallback 进行回调
以上方法对常用操作进行了封装获取数据库连接
应用用户设定的输入参数
调用回调函数
处理一些通用方法外的个性化处理, 也就是 PreparedStatementCallback 类型的参数的
dolnPreparedStatement 方法的回调
警告处理
资源释放
Update 中的回调函数
PreparedStatementCallback 作为一个接口,其中只有一个函数 dolnPreparedStatement ,这个
函数是用于调用通用方法 execute 的时候无法处理的一些个性化处理方法,在 update 中的函数
实现
Spring 中使用 SQL 的执行过程
SQL 语句对应的参数,对应参数的类型清晰明了,这都归功于 Spring 为我们做了封装 ,而
真正的 JDBC 调用其实非常繁琐,需要这么做
所有的操作都是以 pss.setValues(ps) 为人口的
这个pss 所代表的当前类正是 ArgPreparedStatementSetter 其中的 setValues 如下:
对单个参数及类型的匹配处理
query 功能的实现
跟踪 jdbcTemplate 中的 query 方法
rse .extractData(rsToUse )方法负责将结果进行封装并转换至 POJO, rse 当前代表的类为
RowMapperResultSetExtractor ,而在构造 RowMapperResultSetExtractor 的时候我们又将自定义
的 rowMapper 设置了进去 调用代码如下
update 方法以及 query 方法,使用这两个函数示例的 SQL 都是带有参数的,也
就是带有“?”的,那么还有另一种情况是不带有“?”的,Spring 中使用的是另一种处理方式
例如:
与之前的 query 方法最大的不同是少了参数及参数类型的传递,自然也少了 PreparedStatementSetter
类型的封装 既然少了 PreparedStatementSetter 类型的传人,调用的 execute
法自然也会有所改变了
这个 exexute 与之前的 execute 并无太大差别,都是做一些常规的处理,诸如获取连接、释
连接等 ,但是,有一个地方是不一样的,就是 statement 的创建 这里直接使用 connection 创建,
而带有参数的 SQL 使用的是 PreparedStatementCreator 类来创建的。一个是普通的 Statement,
另一个是 PreparedStatement ,两者究竟是何区别呢
PreparedStatement 接口继承 Statement ,并与之在两方面有所不同
PreparedStatement 实例包含已编译的 SQL 语句 这就是使语句“准备好” 包含于
PreparedStatement 对象中的 SQL 语句可 有一个或多个 IN 参数 IN 参数的值在 SQL
语句创建时未被指定 相反的,该语句为每个 IN 参数保留 一个问号 (“?”)作为占位
符 每个问号的值必须在该语句执行之前,通过适当的 setXXX 方法来提供
由于 PreparedStatement 对象已预编译过,所以其执行速度妥快于 Statement 对象 因
此,多次执行的 SQL 语句经常创建为 PreparedStatement 对象,以提高效率
作为 Statement 的子类, PreparedStatement 继承了 Statement 的所有功能 另外,它还添加
了一整套方法 ,用于设置发送给数据库以取代 IN 参数占位符的值 同时, 三种方法 execute
executeQuery 和 executeUpdate 已被更改以使之不再需要参数。 这些方法的 Statement 形式(接
受 SQL 语句参数的形式)不应该用于 PreparedStatement 对象queryForObiect
Spring 中不仅仅为我们提供了 query 方法,还在此基础上做了封装,提供了不同类型的 query
方法
Spring 是如何在返回结果的基础上进行封装的
其实最大的不同还是对于 RowMapper 的使用 SingleColnmnRowMapper 类中的 mapRow
对应的类型转换函数