Spring-Boot 数据库使用实战(一)

Spring-Boot连接数据库基本操作

本文采用mysql为例子,其他数据库同类。

spring.datasource.username=root
spring.datasource.password=123123123
spring.datasource.url=jdbc:mysql://localhost:3306/joinmodel?autoReconnect=true&useSSL=false&SSL=false&characterEncoding=utf8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

使用mysql的同学如出现这个错误Cannot load driver class: com.mysql.jdbc.Driver
需要将mysql驱动jar包引入项目中,使用maven的可以使用

mysql
mysql-connector-java
5.1.38

使用jdbcTemplate操作数据库

  1. 使用@Repository 标注在类上
  2. 使用@Autowired生成jdbcTemplate
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;


/**
 * companyDao
 *
 * @Author weicong
 * @Date 2019 2019/2/26 11:15 PM
 * @Version 1.0
 * @Description TODO
 */
@Repository
@SpringBootApplication
public class CompanyDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public static void main(String[] args) {
        SpringApplication.run(CompanyDao.class,args);
    }
    public void insertData(){
        jdbcTemplate.update("INSERT into company(companyId, cEmail, cPhone, cName, address) values ('acc','vvv','ccc','sss','sss')");
    }
}
1

update后面的sql语句根据数据库来更改

深究updata源码解析

话不多说,上源码

@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 + "]");
        }

        /**
         * Callback to execute the update statement.
         * 这里有一个毁掉方法
         */
        class UpdateStatementCallback implements StatementCallback, SqlProvider {
            @Override
            public Integer doInStatement(Statement stmt) throws SQLException {
                int rows = stmt.executeUpdate(sql);
                if (logger.isTraceEnabled()) {
                    logger.trace("SQL update affected " + rows + " rows");
                }
                return rows;
            }
            @Override
            public String getSql() {
                return sql;
            }
        }

        return updateCount(execute(new UpdateStatementCallback()));
    }
    @Override
    @Nullable
    public  T execute(StatementCallback action) throws DataAccessException {
        Assert.notNull(action, "Callback object must not be null");

        Connection con = DataSourceUtils.getConnection(obtainDataSource());
        Statement stmt = null;
        try {
            stmt = con.createStatement();
            applyStatementSettings(stmt);
            T result = action.doInStatement(stmt);
            handleWarnings(stmt);
            return result;
        }
        catch (SQLException ex) {
            // Release Connection early, to avoid potential connection pool deadlock
            // in the case when the exception translator hasn't been initialized yet.
            String sql = getSql(action);
            JdbcUtils.closeStatement(stmt);
            stmt = null;
            DataSourceUtils.releaseConnection(con, getDataSource());
            con = null;
            throw translateException("StatementCallback", sql, ex);
        }
        finally {
            JdbcUtils.closeStatement(stmt);
            DataSourceUtils.releaseConnection(con, getDataSource());
        }
    }
    private static int updateCount(@Nullable Integer result) {
        Assert.state(result != null, "No update count");
        return result;
    }

  1. update 这个方法就是我们调用的方法,有一个内部类,这个是我们初始化后的入参,实现StatementCallback, SqlProvider两个接口的方法,使execute方法调用这两个方法的时候能够得到update自己重写的方法。
    1.1 doInStatement这个方法里调用的重要的一个方法:executeUpdate,它的实现在于我们使用什么连接池


    image.png
  2. execute这个方法是真正执行sql的方法。
    Connection con = DataSourceUtils.getConnection(obtainDataSource());
    这是获取一个连接stmt = con.createStatement();从连接中创建一个Statement,创建什么养的Statement也是根据我们目前使用了什么连接池来创建的。
    applyStatementSettings(stmt); 这个方法具体实现贴一下源码
/**
     * Prepare the given JDBC Statement (or PreparedStatement or CallableStatement),
     * applying statement settings such as fetch size, max rows, and query timeout.
     * @param stmt the JDBC Statement to prepare
     * @throws SQLException if thrown by JDBC API
     * @see #setFetchSize
     * @see #setMaxRows
     * @see #setQueryTimeout
     * @see org.springframework.jdbc.datasource.DataSourceUtils#applyTransactionTimeout
     */
    protected void applyStatementSettings(Statement stmt) throws SQLException {
        int fetchSize = getFetchSize();
        if (fetchSize != -1) {
            stmt.setFetchSize(fetchSize);
        }
        int maxRows = getMaxRows();
        if (maxRows != -1) {
            stmt.setMaxRows(maxRows);
        }
        DataSourceUtils.applyTimeout(stmt, getDataSource(), getQueryTimeout());
    }

准备给定的JDBC语句(或PreparedStatement或CallableStatement),应用语句设置,如Fetch大小、最大行数和查询超时。
最后一个方法是设置超时时间。这个超时时间方法就不贴了,首先他会获取我们springboot的配置中寻找是否设置了超时时间,如果没有,会使用默认的超时时间
T result = action.doInStatement(stmt);这句是执行sql然后返回一个result,也就是我们在update中实现的方法。
handleWarnings方法是打印一些log之类的
由于update方法实现的是StatementCallback他的范性是Integer类型,所以这个result也是一个Integer类型,最后execute方法返回是一个int,最后走到updateCount方法,这个很简单,我相信大家都能看懂。

if (logger.isDebugEnabled()) {
           logger.debug("Executing SQL update [" + sql + "]");
       }

这段是判断log是否开启debug方法,如果开启,那么输出log。

到这里,update方法就算知道大概了。其他方法都是类似的路线。
本文采用:spring boot2.1.3

你可能感兴趣的:(Spring-Boot 数据库使用实战(一))