1、Spring通过抽象JDBC访问并提供一致的API来简化JDBC的访问。实际操作中,只需要声明SQL、调用合适的api和处理结果集就可以了。
spring主要提供JDBC模板方式、关系数据库对象化方式和SimpleJdbc方式来简化JDBC编程。
JDBC模板方式:框架实现模板设计模式,将可变部分和非可变部分分离,可变部分采用回调接口方式由用户来实现。框架提供了:JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate。
关系数据库操作对象化方式:提供了将关系数据库操作对象化的表示形式,从而使用户可以采用面向对象编程来完成对数据库的访问。如MappingSqlQuery、SqlUpdate、SqlCall、SqlFunction、StoredProcedure等类。这些类的实现一旦建立即可重用并且是线程安全的。
SimpleJdbc方式:提供了SimpleJdbc方式简化编程。SimpleJdbcInsert 、 SimpleJdbcCall用来简化数据库表插入、存储过程或函数访问。
2、框架的JDBC架构
support包:一些工具类
datasource:提供简化访问JDBC数据源工具类,并提供了一些DataSource简单实现类从而能使从这些DataSource获取的连接能自动得到Spring管理事务支持。
core:提供JDBC模板类实现及可变部分的回调接口,还提供SimpleJdbcInsert等简单辅助类
object:提供关系数据库的对象表示形式
3、JDBC模板类
Core包提供了JDBC模板类,其中jdbcTemplate是core包的核心类,其他模板类都是基于它封装完成的。jdbcTemplate类对可变部分采用回调接口的方式实现,如ConnectionCallback通过回调接口返回给用户一个连接,从而可以使用该连接做任何事情、StatementCallback通过回调接口返回给用户一个Statement,从而可以使用该Statement做任何事情等等。
Spring除了提供JdbcTemplate核心类,还提供了基于JdbcTemplate实现的NamedParameterJdbcTemplate类用于支持命名参数绑定、 SimpleJdbcTemplate类用于支持Java5+的可变参数及自动装箱拆箱等特性。
JdbcTemplate类支持的回调类:
- 预编译语句及存储过程创建回调:用于根据JdbcTemplate提供的连接创建相应的语句;
PreparedStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的PreparedStatement;
CallableStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的CallableStatement;
- 预编译语句设值回调:用于给预编译语句相应参数设值;
PreparedStatementSetter:通过回调获取JdbcTemplate提供的PreparedStatement,由用户来对相应的预编译语句相应参数设值;
BatchPreparedStatementSetter:;类似于PreparedStatementSetter,但用于批处理,需要指定批处理大小;
- 自定义功能回调:提供给用户一个扩展点,用户可以在指定类型的扩展点执行任何数量需要的操作;
ConnectionCallback:通过回调获取JdbcTemplate提供的Connection,用户可在该Connection执行任何数量的操作;
StatementCallback:通过回调获取JdbcTemplate提供的Statement,用户可以在该Statement执行任何数量的操作;
PreparedStatementCallback:通过回调获取JdbcTemplate提供的PreparedStatement,用户可以在该PreparedStatement执行任何数量的操作;
CallableStatementCallback:通过回调获取JdbcTemplate提供的CallableStatement,用户可以在该CallableStatement执行任何数量的操作;
- 结果集处理回调:通过回调处理ResultSet或将ResultSet转换为需要的形式;
RowMapper:用于将结果集每行数据转换为需要的类型,用户需实现方法mapRow(ResultSet rs, int rowNum)来完成将每行数据转换为相应的类型。
RowCallbackHandler:用于处理ResultSet的每一行结果,用户需实现方法processRow(ResultSet rs)来完成处理,在该回调方法中无需执行rs.next(),该操作由JdbcTemplate来执行,用户只需按行获取数据然后处理即可。
ResultSetExtractor:用于结果集数据提取,用户需实现方法extractData(ResultSet rs)来处理结果集,用户必须处理整个结果集;
4、关系数据库操作对象化
关系数据库对象化就是用面向对象方式表示关系数据库操作,从而可以复用。JDBC框架将数据库操作封转为一个RdbmsOperation,该对象是线程安全的、可复用的对象,是所有数据库对象的父类。而SqlOperation继承了RdbmsOperation,代表了数据库SQL操作,如SUID等。
数据库操作对象化只有一下几种类型,线程是安全且可复用的:
1、查询:将数据库操作select封转为对象,查询操作的基类是SqlQuery,所有查询都可以使用该类表示。JDBC还提供了一些更容易使用的MappingSqlQueryWithParameter和MappingSqlQuery用于将结果集映射为java对象,查询对象类还提供了两个扩展UpdateSqlQuery和SqlFunction。
2、更新:即增删改操作,将数据库操作insert 、update、delete封装为对象,增删改基类是SqlUpdate,当然还提供了BatchSqlUpdate用于批处理;
3、存储过程及函数:将存储过程及函数调用封装为对象,基类是SqlCall类,提供了StoreProcedure实现。
------------------------
SqlQuery:需要覆盖如下方法来定义一个RowMapper,其中parameters参数表示命名参数或占位符参数值列表,context是由用户传入的上下文数据。
protected RowMapper<UserModel> newRowMapper(Object[] parameters, Map context) { }
其提供了两类方法:
。excute和excuteByNameParam方法:用于查询多行数据,其中excuteByNameParam用于支持命名参数绑定参数;
。findObject和findObjectByNameParam方法:用于查询当行数据,其中findObjectByNameParam用于支持命名参数绑定;
public class UserModelSqlQuery extends SqlQuery<UserModel> {
public UserModelSqlQuery(JdbcTemplate jdbcTemplate) {
//1.设置数据源或JdbcTemplate
//super.setDataSource(jdbcTemplate.getDataSource());
super.setJdbcTemplate(jdbcTemplate);
//2.注入sql语句
super.setSql("select * from test where name=?");
//3.对PreparedStatement参数描述,如命名参数、占位符参数,用于描述参数类型
super.declareParameter(new SqlParameter(Types.VARCHAR));
//可选的编译步骤,当执行查询方法时自动编译,对于编译的SqlQuery不能再对参数进行修改
compile();
}
@Override
protected RowMapper<UserModel> newRowMapper(Object[] parameters, Map context) {
return new UserRowMapper();
}
}
MappingSqlQuery:简化SqlQuery中RowMapper创建,可以直接在实现mapRow(ResultSet rs, int rowNum)来将行数据映射为需要的形式。
public class UserModelMappingSqlQuery extends MappingSqlQuery<UserModel> {
public UserModelMappingSqlQuery(JdbcTemplate jdbcTemplate) {
//1.设置数据源或JdbcTemplate
super.setDataSource(jdbcTemplate.getDataSource());
//2.注入sql语句
super.setSql("select * from test where name=:name");
//3.对PreparedStatement参数描述,如命名参数、占位符参数,用于描述参数类型
super.declareParameter(new SqlParameter("name", Types.VARCHAR));
//可选的编译步骤,当执行查询方法时自动编译,对于编译的SqlQuery不能再对参数进行修改
compile();
}
@Override
protected UserModel mapRow(ResultSet rs, int rowNum) throws SQLException {
UserModel model = new UserModel();
model.setId(rs.getInt("id"));
model.setMyName(rs.getString("name"));
return model;
}
}
其他的差不多类似:
1)UpdatableSqlQuery:提供可更新结果集查询支持,子类实现updateRow(ResultSet rs, int rowNum, Map context)对结果进行更新
2)GenericSqlQuery:提供setRowMapperClass(Class rowMapperClass)方法用于指定RowMapper实现
3)SqlFunction:sql函数包装器,用于支持那些返回单行结果集的查询。该类主要用于返回单行单列结果集
-------------------
SqlUpdate:支持数据库更新操作,即insert、delete和update
提供了update和updateByNamedParam方法用于数据库更新操作,其中updateByNamedParam用于命名参数类型更新。
public class InsertUserModel extends SqlUpdate {
public InsertUserModel(JdbcTemplate jdbcTemplate) {
super.setJdbcTemplate(jdbcTemplate);
super.setSql("insert into test(name) values(?)");
super.declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
}
SqlUpdate update = new SqlUpdate(jdbcTemplate.getDataSource(), updateSql, new int[]{Types.VARCHAR, Types.VARCHAR}); // 简便的方式
===============================
5、Spring JDBC通过实现DaoSupport来支持一致的数据库访问。
。JdbcDaoSupport:用于支持一致的jdbcTemplate访问
。NamedParameterJdbcDaoSupport:继承JdbcDaoSupport,同时提供NamedParameterJdbcTemplate访问
。SimpleJdbcDaoSupport:继承JdbcDaoSupport,同时提供SimpleJdbcTemplate访问
<bean id="abstractDao" abstract="true">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="userDao" class="cn.javass.spring.chapter7.dao.jdbc.UserJdbcDaoImpl" parent="abstractDao"/>