SpringBoot系列之数据库初始化-datasource配置方式

【DB系列】数据库初始化-datasource配置方式 | 一灰灰Blog

在我们的日常业务开发过程中,如果有db的相关操作,通常我们是直接建立好对应的库表结构,并初始化对应的数据,即更常见的情况下是我们在已有表结构基础之下,进行开发;
但是当我们是以项目形式工作时,更常见的做法是所有的库表结构变更、数据的初始、更新等都需要持有对应的sql变更,并保存在项目工程中,这也是使用liqubase的一个重要场景;
将上面的问题进行简单的翻译一下,就是如何实现在项目启动之后执行相应的sql,实现数据库表的初始化?

本文将作为初始化方式的第一篇:基于SpringBoot的配置方式实现的数据初始化

I. 项目搭建

1. 依赖

首先搭建一个标准的SpringBoot项目工程,相关版本以及依赖如下

本项目借助SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA进行开发

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
</dependencies>

本文使用MySql数据库, 版本8.0.31

2. 配置

注意实现初始化数据库表操作的核心配置就在下面,重点关注

配置文件: resources/application.yml

# 默认的数据库名
database:
  name: story

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/${database.name}?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password:
    initialization-mode: always
    platform: mysql
    separator: ;
    data: classpath:config-data.sql
    #data-username: root
    #data-password:
    schema: classpath:config-schema.sql # schema必须也存在,若只存在data,data中的sql也不会被执行

# springboot 2.7+ 版本使用下面这个
#  sql:
#    init:
#      mode: always
#      data-location: classpath:config-data.sql
#      schema-location: classpath:init-schema.sql
logging:
  level:
    root: info
    org:
      springframework:
        jdbc:
          core: debug

上面的配置中,相比较于普通的数据库链接配置,多了几个配置项

  • spring.datasource.initialization-mode: 取值为 always,改成其他的会导致sql不会被执行
  • spring.datasource.platform: mysql
  • spring.datasource.seprator: ; 这个表示sql之间的分隔符
  • spring.datasource.data: classpath:config-data.sql 取值可以是数组,这里存的是初始化数据的sql文件地址
  • spring.datasource.data-username: 上面data对应的sql文件执行用户名
  • spring.datasource.data-password: 上面data对应的sql文件执行用户密码
  • spring.datasource.schema: classpath:config-schema.sql 取值也可以是数组,这里存的是初始化表结构的sql文件地址

3. 初始化sql

上面指定了两个sql,一个是用于建表的ddl,一个是用于初始化数据的dml

resources/config-schema.sql 文件对应的内容如下

CREATE TABLE `user2`
(
    `id`               int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    `third_account_id` varchar(128) NOT NULL DEFAULT '' COMMENT '第三方用户ID',
    `user_name`        varchar(64)  NOT NULL DEFAULT '' COMMENT '用户名',
    `password`         varchar(128) NOT NULL DEFAULT '' COMMENT '密码',
    `login_type`       tinyint      NOT NULL DEFAULT '0' COMMENT '登录方式: 0-微信登录,1-账号密码登录',
    `deleted`          tinyint      NOT NULL DEFAULT '0' COMMENT '是否删除',
    `create_time`      timestamp    NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time`      timestamp    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
    PRIMARY KEY (`id`),
    KEY                `key_third_account_id` (`third_account_id`),
    KEY                `user_name` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4  COMMENT='用户登录表';

resources/config-data.sql 文件对应的内容如下

INSERT INTO `user2` (id, third_account_id, `user_name`, `password`, login_type, deleted)
VALUES (2, '222222-0f85-4dd5-845c-7c5df3746e92', 'admin2', 'admin2', 0, 0);

II. 示例

1. 验证demo

接下来上面的工作准备完毕之后,在我们启动项目之后,正常就会执行上面的两个sql,我们写一个简单的验证demo

@Slf4j
@SpringBootApplication
public class Application implements ApplicationRunner {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        List list = jdbcTemplate.queryForList("select * from user2 limit 2");
        log.info("启动成功,初始化数据: {}\n{}", list.size(), list);
    }
}

2. 问题记录

从上面的过程走下来,看起来很简单,但是在实际的使用过程中,很容易遇到不生效的问题,下面记录一下

2.1 只有初始化数据data.sql,没有schema.sql时,不生效

当库表已经存在时,此时我们可能并没有上文中的config-schema.sql文件,此时对应的配置可能是


spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/${database.name}?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password:
    initialization-mode: always
    platform: mysql
    separator: ; # 默认为 ;
    data: classpath:config-data.sql
    #data-username: root
    #data-password:
    #schema: classpath:config-schema.sql # schema必须也存在,若只存在data,data中的sql也不会被执行

如上面所示,当我们只指定了data时,会发现data对应的sql文件也不会被执行;即要求schema对应的sql文件也必须同时存在

针对上面这种情况,可以考虑将data.sql中的语句,卸载schema.sql中

2.2 版本问题导致配置不生效

在SpringBoot2.5+版本,使用 spring.sql.init 代替上面的配置项

# springboot 2.5+ 版本使用下面这个
spring:
  sql:
    init:
      mode: always
      data-location: classpath:config-data.sql
      schema-location: classpath:init-schema.sql

相关的配置参数说明如下

  • 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`
2.3 mode配置不对导致不生效

当配置完之后发,发现sql没有按照预期的执行,可以检查一下spring.datasource.initialization-mode配置是否存在,且值为always

2.4 重复启动之后,报错

同样上面的项目,在第一次启动时,会执行schema对应的sql文件,创建表结构;执行data对应的sql文件,初始化数据;但是再次执行之后就会报错了,会提示表已经存在

即初始化是一次性的,第一次执行完毕之后,请将spring.datasource.initialization-mode设置为none

3. 小结

本文主要介绍了项目启动时,数据库的初始化方式,当然除了本文中介绍的spring.datasource配置之外,还有spring.jpa的配置方式

对于配置方式不太友好的地方则在于不好自适应控制,若表存在则不执行;若不存在则执行;后面将介绍如何使用DataSourceInitializer来实现自主可控的数据初始化,以及更现代化一些的基于liquibase的数据库版本管理记录

III. 不能错过的源码和相关知识点

0. 项目

1. 微信公众号: 一灰灰Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
初始化DataSource是指在项目启动时设置数据库的初始配置,以便项目能够连接和使用数据库。一种常见的初始化方式是通过配置文件来设置DataSource相关的参数,比如数据库的URL、用户名、密码等。在Spring Boot中,可以使用spring.datasource.*前缀的配置项来进行DataSource初始化配置。使用DataSourceInitializer可以实现自主可控的数据初始化,而基于liquibase的数据库版本管理记录可以提供更现代化的方式来管理数据库的变更和版本控制。 具体的初始化方式可以参考以下资源: 1. 项目工程和源码:可以在GitHub上找到一个名为spring-boot-demo的项目,其中包含了关于初始化DataSource的示例代码和配置文件。 2. 一灰灰Blog微信公众号:该公众号提供了关于项目启动时数据库初始化方式的详细介绍,包括使用spring.datasourcespring.jpa配置方式。 3. 文章:在一篇名为"基于SpringBoot配置方式实现的数据初始化"的文章中,详细介绍了使用Spring Boot进行数据初始化的步骤和配置方法。 通过以上资源,你可以了解到如何在项目启动时进行DataSource初始化配置,并选择适合自己项目的方式来实现数据初始化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [SpringBoot系列数据库初始化-datasource配置方式](https://blog.csdn.net/liuyueyi25/article/details/128471764)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一灰灰blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值