美文网首页程序员
Java - JdbcTemplate底层调用逻辑

Java - JdbcTemplate底层调用逻辑

作者: 夹胡碰 | 来源:发表于2021-01-10 01:10 被阅读0次

    版本: spring-boot 2.0.5.RELEASE

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.17</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    

    对应的spring-jdbc版本5.0.9.RELEASE

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.0.9.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    

    application.yml

    spring:
      datasource:
        username: root
        password: root
        url: jdbc:mysql://localhost:3306/datamiddle?characterEncoding=utf8&useSSL=true&rewriteBatchedStatements=true
        driver-class-name: com.mysql.jdbc.Driver
    

    1. JdbcTemplate使用

    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Transactional
    public String test(){
        return jdbcTemplate.queryForList("select * from user where id = 1").toString();
    }
    

    2. JdbcTemplate原理

    Spring Boot 启动,通过配置文件application.yml,加载DataSource(HikariDataSource),之后加载JdbcTemplate

    注意:

    1. Spring Boot 2.X使用的是HikariDataSource作为数据库连接池,1.5使用的是tomcat jdbc pool
    2. DataSource可直接作为jdbc操作数据库,而JdbcTemplate是进一步的封装,省去了查询封装,关闭连接等操作。
    public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
    
        public JdbcTemplate() {
        }
        // 注入HikariDataSource
        public JdbcTemplate(DataSource dataSource) {
            this.setDataSource(dataSource);
            this.afterPropertiesSet();
        }
        ...
    }
    

    3. JdbcTemplate查询操作原理解析

    jdbcTemplate.queryForList方法为例,通过重点代码查看内部执行原理

    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 (this.logger.isDebugEnabled()) {
            this.logger.debug("Executing SQL query [" + sql + "]");
        }
    
        class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
            QueryStatementCallback() {
            }
    
            @Nullable
            public T doInStatement(Statement stmt) throws SQLException {
                ResultSet rs = null;
    
                Object var3;
                try {
                    rs = stmt.executeQuery(sql);
                    var3 = rse.extractData(rs);
                } finally {
                    JdbcUtils.closeResultSet(rs);
                }
    
                return var3;
            }
    
            public String getSql() {
                return sql;
            }
        }
    
        return this.execute((StatementCallback)(new QueryStatementCallback()));
    }
    
    • 使用DataSource原生执行sql查询
    public <T> T execute(StatementCallback<T> action) throws DataAccessException {
        Assert.notNull(action, "Callback object must not be null");
        Connection con = DataSourceUtils.getConnection(this.obtainDataSource()); // 通过DataSource获取Connection
        Statement stmt = null;
    
        Object var11;
        try {
            stmt = con.createStatement(); // 获取Statement
            this.applyStatementSettings(stmt);
            T result = action.doInStatement(stmt); // 执行QueryStatementCallback的executeQuery
            this.handleWarnings(stmt);
            var11 = result;
        } catch (SQLException var9) {
            String sql = getSql(action);
            JdbcUtils.closeStatement(stmt);
            stmt = null;
            DataSourceUtils.releaseConnection(con, this.getDataSource());
            con = null;
            throw this.translateException("StatementCallback", sql, var9);
        } finally {
            JdbcUtils.closeStatement(stmt); // 关闭连接
            DataSourceUtils.releaseConnection(con, this.getDataSource()); // 关闭连接
        }
    
        return var11; // 返回查询结果
    }
    

    相关文章

      网友评论

        本文标题:Java - JdbcTemplate底层调用逻辑

        本文链接:https://www.haomeiwen.com/subject/jftkaktx.html