springboot 启动时初始化数据库的步骤
作者:鲸冬香 发布时间:2024-01-26 18:32:57
问题描述
在spring-boot启动时,希望能执行相应的sql文件来初始化数据库。
使用配置文件初始化数据库
可以在spring-boot的配置文件application.yml中设置要初始化的sql文件。这是最简单的方法,只需要添加属性就可以实现。
首先设置spring.datasource.initialization-mode=always表示任何类型数据库都进行数据库初始化,默认情况下,spring-boot会自动加载data.sql或data-${platform}.sql文件来初始化数据库。可以通过设置不同的数据库平台来改变启动的脚本名称。
例如设置spring.datasource.platform=mysql,就会加载data-mysql.sql的数据库脚本。把数据库脚本文件放在resources路径下即可。
如果项目使用的是flyway管理数据库的话,可以直接在flyway路径下添加一个新版本的sql文件,flyway也会自动执行sql文件并记录版本信息。
通过代码初始化数据库
如果通过配置文件不能满足需求,可以通过代码来初始化数据库。
只需要提供DataSourceInitializer这个bean,spring-boot启动时就会根据DataSourceInitializer来初始化数据库了。
@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
resourceDatabasePopulator.addScript(new ClassPathResource("/data.sql"));
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
dataSourceInitializer.setDataSource(dataSource);
dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
return dataSourceInitializer;
}
在此基础上,我们可以自定义注解,通过获取注解上的sql文件路径,来达到通过注解初始化数据库目的,这样更方便简洁。
首先定义注解InitDataSource:
/**
* 用于补充:Hibernate无法自动创建视图的缺陷。
* 系统启动时(hibernate根据entity创建完基本的数据表后),开始执行本注解下的sql文件中的SQL语言。
* 使用方法:
* @InitDataSource("sql文件路径(相对于resources路径下)") ---- 注解到对应的类上
* 比如:@InitDataSource("db/view/createView.sql)")
* 使用示例请参见:ResourceApplication.java
* 预了解详细的实现过程请参考:WebConfig.java 的 dataSourceInitializer方法
* @author huangtingxiang
*/
@Target({ElementType.TYPE}) // 该注解用于类上
@Retention(RetentionPolicy.RUNTIME) // 在运行时起作用
@Component
public @interface InitDataSource {
String\[\] value();
}
然后通过ClassPathScanningCandidateComponentProvider这个类来扫描spring组件上InitDataSource注解的值,将值取出,添加到DataSourceInitializer的初始化脚本中:
@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
// 扫描com.mengyunzhi.measurement 包 找到InitDataSource注解的类(注解需使用到实现类上)
ClassPathScanningCandidateComponentProvider provider
= new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AnnotationTypeFilter(InitDataSource.class)); //添加包含的过滤信息
for (BeanDefinition beanDef : provider.findCandidateComponents("com.mengyunzhi.measurement")) {
Class<?> cl = null;
try {
cl = Class.forName(beanDef.getBeanClassName());
InitDataSource initDataSource = cl.getAnnotation(InitDataSource.class);
String\[\] sqlFiles = initDataSource.value();
for (String sql: sqlFiles) {
// 如果sql文件存在 加入数据库初始化中 否则抛出异常终止执行
ClassPathResource resource = new ClassPathResource("/" + sql);
if (resource.exists()) {
resourceDatabasePopulator.addScript(resource);
} else {
throw new DataSourceInitializerException("未找到资源文件:" + sql, cl);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
dataSourceInitializer.setDataSource(dataSource);
dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
return dataSourceInitializer;
}
这样一来,只需要在spring-boot类上使用@InitDataSource({"data.sql"})注解,就可以自动进行数据库的初始化操作了。
来源:https://segmentfault.com/a/1190000021705562


猜你喜欢
- 这里的搜索功能主要基于表单get提交实现的<form action="/backend/auditList" me
- 常用配置以下配置能使用File -> New Projects Settings -> Settings for New Pro
- iframe的背景颜色在IE下为window的当前窗口颜色(默认白色,可以在显示外观处对其进行设置),这导致在大幅背景上插入iframe时,
- 需求:获取oracle表增量信息,发送至udp514端口,支持ip配置步骤:(1)需要的jar oracle的 odbc5.ja
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN&q
- php读写二进制文件可以使用pack和unpack函数。今天要处理一个二进制文件的问题,所以需要用一下,特意了解一下pack的用法,unpa
- Python深搜版:核心在于带随机的深搜(见代码第23到27行,其实也可以用22行代替这几行代码,你可以试着把第24行的数字4改大或者改小,
- Observer模式也叫观察者模式,是由GoF提出的23种软件设计模式的一种。Observer模式是行为模式之一,它的作用是当一个对象的状态
- python的os module中有fork()函数用于生成子进程,生成的子进程是父进程的镜像,但是它们有各自的地址空间,子进程复制一份父进
- 本篇文章主要介绍vue添加标签,废话不多说了,下面上具体代码效果如下:html<div id="app">&
- 今天下午主要做了个实验,是针对 测试表的列,进行添加,修改,删除的。做法如下: 增加一列: alter table emp4 add tes
- 下面的代码是从kesion系统扒下的,确实不错,支持utf8格式。代码如下:'===========================
- 用python画柱状图容易,但是如何对不同柱子使用不同颜色呢?同时在柱子顶端显示精确数值?主要用的方法为:atplotlib.pyplot.
- 远程登录控制台Scrapy附带一个内置的telnet控制台,用于检查和控制Scrapy运行过程。telnet控制台只是一个运行在scrapp
- 前言由于后端使用php、node.js、java等进行大量的图片下载操作可能会导致服务器负载过高,所以将图片下载转移到客户端是个不错的选择,
- 引言python中的模块、库、包有什么区别?module:一个 .py 文件就是个 modulelib:抽象概念,和另外两个不是一类,只要你
- 1、下载pycharmpycharm是一种Python IDE,能够帮助我们在编写代码时提高效率。网上提供的有专业版和教育版之分。专业版是收
- Python读取配置文件-ConfigParser二次封装直接上上代码test.conf[database]connect = mysqls
- 共享标签默认情况下,git push 命令并不会传送标签到远程仓库服务器上。在创建完标签后,你必须显式地(手动)推送标签到远程服务
- 源码及注释:import pygamefrom sys import exitfrom random import randintimpor