Spring中的JDBC API

1. Spring中的JDBC

1.1 JdbcTemplate的诞生

JDBC作为Java平台访问关系数据库的标准API,其成功是有目共睹的。为了避免在JDBC API在使用中的种种尴尬局面(几乎程式一样的代码,繁琐的异常处理),Spring框架提出了JdbcTemplate作为数据访问的Helper类。JdbcTemplate是整个Spring数据抽象层提供的所有JDBC API最佳实践的基础,框架内其他更加方便的Helper类以及更高层次的抽象,全部构建于JdbcTemplate之上。概括地说,JdbcTemplate主要关注如下两个事情:

  • 封装所有基于JDBC的数据访问代码,以统一的格式和规范来使用JDBC API。所有基于JDBC的数据访问需求现在全部通过JdbcTemplate进行,从而避免了让繁琐易错的基于JDBC API的数据访问代码散落于系统各处。
  • SQLException所提供的异常信息在框架内进行统一转译,将基于JDBC的数据访问异常纳入Spring自身的异常层次体系中,统一了数据接口的定义,简化了客户端代码对数据访问异常的处理。

1.2 模版方法模式简介

模版方法模式主要用于对算法或者行为逻辑进行封装,即如果多个类中存在某些相似的算法逻辑或者行为逻辑,可以将这些相似的逻辑提取到模板方法类(抽象类)中实现,然后让相应的子类根据需要实现某些自定义的逻辑。

1.3 JdbcTemplate的演化

我们可以看一下直接使用JDBC API进行数据访问的,会发现除了小部分的差异以外,几乎都是按照同一个流程下来的:

// 取得数据连接
con = getDataSource().getConnection();
// 根据Connection创建对应的PreparedStatement
ps = con.prepareStatement(..);
// 根据传入的SQL语句或者参数。借助PreparedStatement进行数据库的更新或者查询。
ps.executeUpdate(sql)
// 如果是查询操作,那么可以按如下代码对结果集进行遍历,抽取查询后的结果
ResultSet rs = ps.executeQuery(sql);
while (rs.next()) {
    processResultRow(rs);
}
// 关闭相应的PreparedStatement
ps.close(); ps = null;
//处理数据库访问异常
catch(SQLExecption e) {...}
// 关闭数据库连接以避免连接泄漏导致系统崩溃
finally {con.close();}

对于多个DAO中充斥的几乎相同的JDBC代码,我们可以将共有的一些行为提取到模板方法类中,而特有的操作,比如每次执行不同的更新,或者每次针对不同的查询结果进行不同的处理等行为,则放入具体的子类中实现。但是,仅使用模板方式,JdbcTemplate将会顶着abstract的帽子,并不能独立使用,所以,Spring框架还引入了相应的Callback接口定义,以避免每次使用该Helper类的时候都需要进行子类化。该Callback接口的定义为

public interface StatementCallback<T> {
    T doInStatement(Statement var1) throws SQLException, DataAccessException;
}

引入该接口后,我们的JdbcTemplate就可以摆脱abstract的帽子,作为一个真正的Helper类来存在了。

public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
    public <T> T execute(StatementCallback<T> action) throws DataAccessException {
        Connection con = null;
        Statement stmt = null;
        try {
            con = getConnection();
            stmt = con.createStatement();
            T result = action.doWithStatement(stmt);
        } catch (SQLException e) {
            DataAccessException ex = translateSQLException(e);
            throws ex;
        } finally {
            closeStatement(stmt);
            releaseConnection(con);
        }
    }
    ...// 其他方法定义
}

要想在相应的DAO实现类中使用JdbcTemplate,只需要根据情况提供参数和相应的StatementCallback就行了,如下代码演示了JdbcTemplate原型的使用:

JdbcTemplate jdbcTemplate = ...;
final String sql = "update...";
StatementCallback callback = new StatementCallback() {
    public Object doWithStatement(Statement stmt) {
        return new Integer(stmt.executeUpdate(sql));
    };
JdbcTemplate.execute(callback);
}

这样,开发人员只需要关心doWithStatement中与数据访问有关的东西,对于JDBC底层的细节则不需要过多的考虑。

Spring中的JDBC API

上一篇:FileWriter向文件中写入内容


下一篇:MySQL存储过程简介