在spring-boot启动时,但愿能执行相应的sql文件来初始化数据库。java
能够在spring-boot的配置文件application.yml中设置要初始化的sql文件。这是最简单的方法,只须要添加属性就能够实现。mysql
首先设置spring.datasource.initialization-mode=always
表示任何类型数据库都进行数据库初始化,默认状况下,spring-boot会自动加载data.sql
或data-${platform}.sql
文件来初始化数据库。能够经过设置不一样的数据库平台来改变启动的脚本名称。spring
例如设置spring.datasource.platform=mysql
,就会加载data-mysql.sql的数据库脚本。把数据库脚本文件放在resources路径下便可。sql
若是项目使用的是flyway管理数据库的话,能够直接在flyway路径下添加一个新版本的sql文件,flyway也会自动执行sql文件并记录版本信息。数据库
若是经过配置文件不能知足需求,能够经过代码来初始化数据库。
只须要提供DataSourceInitializer这个bean
,spring-boot启动时就会根据DataSourceInitializer来初始化数据库了。app
@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:ide
/** * 用于补充: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的初始化脚本中:spring-boot
@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"})
注解,就能够自动进行数据库的初始化操做了。hibernate
参考文章:
Spring boot. Run SQL scripts and get data on application startupcode