zoukankan      html  css  js  c++  java
  • spring jdbcTemplate源码剖析

      本文浅析 spring jdbcTemplate 源码,主要是学习其设计精髓。模板模式、巧妙的回调

    一、jdbcTemplate 类结构

    ①、JdbcOperations : 接口定义了方法,如

    <T> T execute(StatementCallback<T> action) throws DataAccessException;

    void execute(String sql) throws DataAccessException;

    <T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;

    。。。

    ②、JdbcAccessor : 定义了数据源。

    ③、实现JdbcOperations接口定义的方法

    二、jdbcTemplate 模板模式

    1、我们看下execute(StatementCallback<T> action)实现 (核心

    public <T> T execute(StatementCallback<T> action) throws DataAccessException {
            Assert.notNull(action, "Callback object must not be null");
    
            Connection con = DataSourceUtils.getConnection(getDataSource());
            Statement stmt = null;
            try {
                Connection conToUse = con;
                if (this.nativeJdbcExtractor != null &&
                        this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
                    conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
                }
                stmt = conToUse.createStatement();
                applyStatementSettings(stmt);
                Statement stmtToUse = stmt;
                if (this.nativeJdbcExtractor != null) {
                    stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
                }
                T result = action.doInStatement(stmtToUse); // 回调
                handleWarnings(stmt);
                return result;
            }
            catch (SQLException ex) {
                JdbcUtils.closeStatement(stmt);
                stmt = null;
                DataSourceUtils.releaseConnection(con, getDataSource());
                con = null;
                throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
            }
            finally {
                JdbcUtils.closeStatement(stmt);
                DataSourceUtils.releaseConnection(con, getDataSource());
            }
        }

    2、再看下 execute(String sql) 源码

    public void execute(final String sql) throws DataAccessException {
            if (logger.isDebugEnabled()) {
                logger.debug("Executing SQL statement [" + sql + "]");
            }
            class ExecuteStatementCallback implements StatementCallback<Object>, SqlProvider {
                @Override
                public Object doInStatement(Statement stmt) throws SQLException {
                    stmt.execute(sql); // JAVA  jdbc
                    return null;
                }
                @Override
                public String getSql() {
                    return sql;
                }
            }
            execute(new ExecuteStatementCallback()); // 调用上述T execute(StatementCallback<T> action) 
        }

     由此,可以知道,我们平时常用的execute(final String sql) 方法,底层帮我们做了很多事情,如创建默认的ExecuteStatementCallback,采用回调的方式,由模板去执行sql,关闭链接

     3、T query(final String sql, final ResultSetExtractor<T> rse) 源码实现

    @Override
        public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
            Assert.notNull(sql, "SQL must not be null");
            Assert.notNull(rse, "ResultSetExtractor must not be null");
            if (logger.isDebugEnabled()) {
                logger.debug("Executing SQL query [" + sql + "]");
            }
            class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
                @Override
                public T doInStatement(Statement stmt) throws SQLException {
                    ResultSet rs = null;
                    try {
                        rs = stmt.executeQuery(sql);
                        ResultSet rsToUse = rs;
                        if (nativeJdbcExtractor != null) {
                            rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
                        }
                        return rse.extractData(rsToUse);
                    }
                    finally {
                        JdbcUtils.closeResultSet(rs);
                    }
                }
                @Override
                public String getSql() {
                    return sql;
                }
            }
            return execute(new QueryStatementCallback());
        }
    View Code

     4、update(final String sql) 源码

    @Override
        public int update(final String sql) throws DataAccessException {
            Assert.notNull(sql, "SQL must not be null");
            if (logger.isDebugEnabled()) {
                logger.debug("Executing SQL update [" + sql + "]");
            }
            class UpdateStatementCallback implements StatementCallback<Integer>, SqlProvider {
                @Override
                public Integer doInStatement(Statement stmt) throws SQLException {
                    int rows = stmt.executeUpdate(sql);
                    if (logger.isDebugEnabled()) {
                        logger.debug("SQL update affected " + rows + " rows");
                    }
                    return rows;
                }
                @Override
                public String getSql() {
                    return sql;
                }
            }
            return execute(new UpdateStatementCallback());
        }
    View Code
  • 相关阅读:
    ML_入门
    subnet partition
    科比投球预测-python实例
    javascript高级程序设计》第18章 javascript与xml
    《javascript高级程序设计》第17章 错误处理与调试
    《javascript高级程序设计》 第16章 HTML5 脚本编程
    《javascript高级程序设计》 第14章 表单脚本
    《javascript高级程序设计》第13章 事件event
    《javascript高级程序设计》第12 章 DOM2 和DOM3
    《javascript高级程序设计》第11章 DOM 扩展DOM Extensions
  • 原文地址:https://www.cnblogs.com/chenmo-xpw/p/5536592.html
Copyright © 2011-2022 走看看