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的可以使用
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>

使用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<Integer>, 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> T execute(StatementCallback<T> 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<Integer>, 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>他的范性是Integer类型,所以这个result也是一个Integer类型,最后execute方法返回是一个int,最后走到updateCount方法,这个很简单,我相信大家都能看懂。

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

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容