前几天Spring Boot 2.5.0公布了,其中提到了对于Datasource初始化机制的调整,有读者私信想理解这方面做了什么调整。那么明天就要具体说说这个从新设计的配置内容,并结合实际状况说说我的了解和实际倡议。

弃用内容

先来纠正一个误区。次要之前在版本更新介绍的时候,存在一些表述上的问题。导致局部读者认为这次的更新是Datasource自身初始化的调整,但其实并不是。这次从新设计的只是对Datasource脚本初始化机制的从新设计。

先来看看这次被弃用局部的内容(位于org.springframework.boot.autoconfigure.jdbc.DataSourceProperties),如果你有用过这些配置内容,那么新配置就很容易了解了。

    /**     * Mode to apply when determining if DataSource initialization should be performed     * using the available DDL and DML scripts.     */    @Deprecated    private DataSourceInitializationMode initializationMode = DataSourceInitializationMode.EMBEDDED;    /**     * Platform to use in the DDL or DML scripts (such as schema-${platform}.sql or     * data-${platform}.sql).     */    @Deprecated    private String platform = "all";    /**     * Schema (DDL) script resource references.     */    private List<String> schema;    /**     * Username of the database to execute DDL scripts (if different).     */    @Deprecated    private String schemaUsername;    /**     * Password of the database to execute DDL scripts (if different).     */    @Deprecated    private String schemaPassword;    /**     * Data (DML) script resource references.     */    @Deprecated    private List<String> data;    /**     * Username of the database to execute DML scripts (if different).     */    @Deprecated    private String dataUsername;    /**     * Password of the database to execute DML scripts (if different).     */    @Deprecated    private String dataPassword;    /**     * Whether to stop if an error occurs while initializing the database.     */    @Deprecated    private boolean continueOnError = false;    /**     * Statement separator in SQL initialization scripts.     */    @Deprecated    private String separator = ";";    /**     * SQL scripts encoding.     */    @Deprecated    private Charset sqlScriptEncoding;

对应到配置文件里的属性如下(这里仅列出局部,就不全副列出了,次要就是对应下面源码中的属性):

spring.datasource.schema=spring.datasource.schema-username=spring.datasource.schema-password=...

这些配置次要用来指定数据源初始化之后要用什么用户、去执行哪些脚本、遇到谬误是否持续等性能。

新的设计

Spring Boot 2.5.0开始,启用了全新的配置形式,咱们能够从这个类org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties里看到详情。

上面咱们通过一个简略的例子来体验这个性能的作用。

  • 创立一个Spring Boot的根底利用,并在pom.xml中引入和mysql的依赖:
<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId></dependency>
  • 在配置文件中减少数据源和初始化数据源的配置,具体如下:
spring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=rootspring.datasource.password=spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# Spring Boot 2.5.0 init schema & data# 执行初始化脚本的用户名称spring.sql.init.username=root# 执行初始化脚本的用户明码spring.sql.init.password=# 初始化的schema脚本地位spring.sql.init.schema-locations=classpath*:schema-all.sql
  • 依据下面配置的定义,接下来就在resource目录下,创立脚本文件schema-all.sql,并写入一些初始化表构造的脚本
create table test.user_info(    id          int unsigned auto_increment comment '用户id'        primary key,    open_id     varchar(255)     default '' null comment '微信小程序openid',    nick_name   varchar(255)     default '' null comment '微信名',    head_img    varchar(255)     default '' null comment '微信头像',    sex         varchar(255)     default '' null comment '性别',    phone       varchar(255)     default '' null comment '手机',    province    varchar(255)     default '' null comment '注册地址:省',    city        varchar(255)     default '' null comment '注册地址:城市',    country     varchar(255)     default '' null comment '注册地址:县/区',    status      tinyint unsigned default 0  not null comment '是否标记删除 0:否 1:是',    create_time datetime                    not null comment '创立工夫',    update_time datetime                    not null comment '更新工夫')comment '用户表';
  • 实现下面步骤之后,启动利用。而后关上MySQL客户端,能够看到在test库下,多了一个user_info

通过下面的例子,不难想到这样的性能次要能够用来治理利用启动与数据库配置的主动执行,以缩小利用部署过程中手工执行的内容,升高利用部署的执行步骤。

配置详解

除了下面用到的配置属性之外,还有一些其余的配置,上面具体解说一下作用。

  • spring.sql.init.enabled:是否启动初始化的开关,默认是true。如果不想执行初始化脚本,设置为false即可。通过-D的命令行参数会更容易管制。
  • spring.sql.init.usernamespring.sql.init.password:配置执行初始化脚本的用户名与明码。这个十分有必要,因为平安治理要求,通常给业务利用调配的用户对一些建表删表等命令没有权限。这样就能够与datasource中的用户离开治理。
  • spring.sql.init.schema-locations:配置与schema变更相干的sql脚本,可配置多个(默认用;宰割)
  • spring.sql.init.data-locations:用来配置与数据相干的sql脚本,可配置多个(默认用;宰割)
  • spring.sql.init.encoding:配置脚本文件的编码
  • spring.sql.init.separator:配置多个sql文件的分隔符,默认是;
  • spring.sql.init.continue-on-error:如果执行脚本过程中碰到谬误是否持续,默认是false`;所以,下面的例子第二次执行的时候会报错并启动失败,因为第一次执行的时候表曾经存在。

利用倡议

对于这些配置的利用,置信聪慧的你肯定会把它与数据库的版本治理分割起来(因为能够主动的执行脚本)。

那么依附这些配置,是否能够胜任业务利用部署时候数据库初始化的自动化实现呢?

集体认为就上述所介绍的配置,尽管具备了肯定的主动执行能力。但因为缺失对以后环境的判断能力,所以要应答理论的部署场景来说,还是远远不够的。

如果要自动化的治理数据库表构造、初始化数据的话,我的倡议是:

  1. 默认提供的这个初始化性能能够且仅用于单元测试,主动创立数据库构造与初始化数据,应用结束后销毁。能够不便的管制每次单元测试的执行环境统一。
  2. 利用在环境部署的时候,还是要应用之前介绍过的Flyway来实现,如何应用可见之前的分享:应用Flyway来治理数据库版本。
  3. 联结Flyway一起应用,通过org.springframework.jdbc.datasource.init.DataSourceInitializer来定义更简单的执行逻辑。

更多本系列收费教程连载「点击进入汇总目录」

代码示例

本文的相干例子能够查看上面仓库中的chapter3-13目录:

  • Github:https://github.com/dyc87112/SpringBoot-Learning/
  • Gitee:https://gitee.com/didispace/SpringBoot-Learning/

原创不易,如果您感觉本文不错,欢送Star反对,您的关注是我保持的能源!

欢送关注我的公众号:程序猿DD,分享其余中央看不到的常识与思考