- 前言
- 第一部分 核心实现
- 第 1 章 Spring 整体架构和环境搭建
- 第 2 章 容器的基本实现
- 第 3 章 默认标签的解析
- 第 4 章 自定义标签的解析
- 第 5 章 bean 的加载
- 第 6 章 容器的功能扩展
- 第 7 章 AOP
- 第二部分 企业应用
- 第 8 章 数据库连接 JDBC
- 第 9 章 整合 MyBatis
- 第 10 章 事务
- 第 11 章 SpringMVC
- 第 12 章 远程服务
- 第 13 章 Spring 消息
8.2 save/update 功能的实现
我们以上面的例子为基础开始分析 Spring 中对 JDBC 的支持,首先寻找整个功能的切入点,在示例中我们可以看到所有的数据库操作都封装在了 UserServiceImpl 中,而 UserServiceImpl 中的所有数据库操作又以其内部属性 jdbcTemplate 为基础。这个 jdbcTemplate 可以作为源码分析的切入点,我们一起看看它是如何实现又是如何被初始化的。
在 UserServiceImpl 中 jdbcTemplate 的初始化是从 setDataSource 函数开始的,DataSource 实例通过参数注入,DataSource 的创建过程是引入第三方的连接池,这里不做过多介绍。DataSource 是整个数据库操作的基础,里面封装了整个数据库的连接信息。我们首先以保存实体类为例进行代码跟踪。
public void save(User user) {
jdbcTemplate.update("insert into user(name,age,sex)values(?,?,?)",
new Object[] { user.getName(), user.getAge(),
user.getSex() }, new int[] { java.sql.Types.VARCHAR,
java.sql.Types.INTEGER, java.sql.Types.VARCHAR });
}
对于保存一个实体类来讲,在操作中我们只需要提供 SQL 语句以及语句中对应的参数和参数类型,其他操作便可以交由 Spring 来完成了,这些工作到底包括什么呢?进入 jdbcTemplate 中的 update 方法。
public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException {
return update(sql, newArgTypePreparedStatementSetter(args, argTypes));
}
public int update(String sql, PreparedStatementSetter pss) throws DataAccessException {
return update(new SimplePreparedStatementCreator(sql), pss);
}
进入 update 方法后,Spring 并不是急于进入核心处理操作,而是先做足准备工作,使用 ArgTypePreparedStatementSetter 对参数与参数类型进行封装,同时又使用 Simple PreparedStatement Creator 对 SQL 语句进行封装。至于为什么这么封装,暂且留下悬念。
经过了数据封装后便可以进入了核心的数据处理代码了。
protected int update(final PreparedStatementCreator psc, final PreparedStatementSetter pss)
throws DataAccessException {
logger.debug("Executing prepared SQL update");
return execute(psc, new PreparedStatementCallback<Integer>() {
public Integer doInPreparedStatement(PreparedStatement ps) throws
SQLException {
try {
if (pss != null) {
//设置 PreparedStatement 所需的全部参数。
pss.setValues(ps);
}
int rows = ps.executeUpdate();
if (logger.isDebugEnabled()) {
logger.debug("SQL update affected " + rows + " rows");
}
return rows;
}
finally {
if (pss instanceof ParameterDisposer) {
((ParameterDisposer) pss).cleanupParameters();
}
}
}
});
}
如果读者了解过其他操作方法,可以知道 execute 方法是最基础的操作,而其他操作比如 update、query 等方法则是传入不同的 PreparedStatementCallback 参数来执行不同的逻辑。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论