Introduce a shared abstraction for database initialization

Currently used by Spring Batch, Spring Integration, Spring Session and Quartz.

Signed-off-by: Yanming Zhou <zhouyanming@gmail.com>
This commit is contained in:
Yanming Zhou 2025-05-06 12:28:46 -07:00
parent 0386fbeb16
commit 446c271e83
13 changed files with 259 additions and 359 deletions

View File

@ -16,14 +16,10 @@
package org.springframework.boot.autoconfigure.batch;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.jdbc.init.PlatformPlaceholderDatabaseDriverResolver;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.util.StringUtils;
import org.springframework.boot.jdbc.init.PropertiesBasedDataSourceScriptDatabaseInitializer;
/**
* {@link DataSourceScriptDatabaseInitializer} for the Spring Batch database. May be
@ -33,54 +29,19 @@ import org.springframework.util.StringUtils;
* @author Vedran Pavic
* @author Andy Wilkinson
* @author Phillip Webb
* @author Yanming Zhou
* @since 2.6.0
*/
public class BatchDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer {
public class BatchDataSourceScriptDatabaseInitializer
extends PropertiesBasedDataSourceScriptDatabaseInitializer<BatchProperties.Jdbc> {
/**
* Create a new {@link BatchDataSourceScriptDatabaseInitializer} instance.
* @param dataSource the Spring Batch data source
* @param properties the Spring Batch JDBC properties
* @see #getSettings
*/
public BatchDataSourceScriptDatabaseInitializer(DataSource dataSource, BatchProperties.Jdbc properties) {
this(dataSource, getSettings(dataSource, properties));
}
/**
* Create a new {@link BatchDataSourceScriptDatabaseInitializer} instance.
* @param dataSource the Spring Batch data source
* @param settings the database initialization settings
* @see #getSettings
*/
public BatchDataSourceScriptDatabaseInitializer(DataSource dataSource, DatabaseInitializationSettings settings) {
super(dataSource, settings);
}
/**
* Adapts {@link BatchProperties.Jdbc Spring Batch JDBC properties} to
* {@link DatabaseInitializationSettings} replacing any {@literal @@platform@@}
* placeholders.
* @param dataSource the Spring Batch data source
* @param properties batch JDBC properties
* @return a new {@link DatabaseInitializationSettings} instance
* @see #BatchDataSourceScriptDatabaseInitializer(DataSource,
* DatabaseInitializationSettings)
*/
public static DatabaseInitializationSettings getSettings(DataSource dataSource, BatchProperties.Jdbc properties) {
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties));
settings.setMode(properties.getInitializeSchema());
settings.setContinueOnError(true);
return settings;
}
private static List<String> resolveSchemaLocations(DataSource dataSource, BatchProperties.Jdbc properties) {
PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver();
if (StringUtils.hasText(properties.getPlatform())) {
return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema());
}
return platformResolver.resolveAll(dataSource, properties.getSchema());
super(dataSource, properties);
}
}

View File

@ -17,7 +17,7 @@
package org.springframework.boot.autoconfigure.batch;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.sql.init.DatabaseInitializationMode;
import org.springframework.boot.jdbc.init.DatabaseInitializationProperties;
import org.springframework.transaction.annotation.Isolation;
/**
@ -63,7 +63,7 @@ public class BatchProperties {
}
public static class Jdbc {
public static class Jdbc extends DatabaseInitializationProperties {
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
+ "batch/core/schema-@@platform@@.sql";
@ -78,27 +78,11 @@ public class BatchProperties {
*/
private Isolation isolationLevelForCreate;
/**
* Path to the SQL file to use to initialize the database schema.
*/
private String schema = DEFAULT_SCHEMA_LOCATION;
/**
* Platform to use in initialization scripts if the @@platform@@ placeholder is
* used. Auto-detected by default.
*/
private String platform;
/**
* Table prefix for all the batch meta-data tables.
*/
private String tablePrefix;
/**
* Database schema initialization mode.
*/
private DatabaseInitializationMode initializeSchema = DatabaseInitializationMode.EMBEDDED;
public boolean isValidateTransactionState() {
return this.validateTransactionState;
}
@ -115,22 +99,6 @@ public class BatchProperties {
this.isolationLevelForCreate = isolationLevelForCreate;
}
public String getSchema() {
return this.schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getPlatform() {
return this.platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getTablePrefix() {
return this.tablePrefix;
}
@ -139,12 +107,9 @@ public class BatchProperties {
this.tablePrefix = tablePrefix;
}
public DatabaseInitializationMode getInitializeSchema() {
return this.initializeSchema;
}
public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
this.initializeSchema = initializeSchema;
@Override
public String getDefaultSchemaLocation() {
return DEFAULT_SCHEMA_LOCATION;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,15 +16,13 @@
package org.springframework.boot.autoconfigure.integration;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.jdbc.init.PlatformPlaceholderDatabaseDriverResolver;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.util.StringUtils;
import org.springframework.boot.jdbc.init.PropertiesBasedDataSourceScriptDatabaseInitializer;
/**
* {@link DataSourceScriptDatabaseInitializer} for the Spring Integration database. May be
@ -32,9 +30,11 @@ import org.springframework.util.StringUtils;
*
* @author Vedran Pavic
* @author Andy Wilkinson
* @author Yanming Zhou
* @since 2.6.0
*/
public class IntegrationDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer {
public class IntegrationDataSourceScriptDatabaseInitializer
extends PropertiesBasedDataSourceScriptDatabaseInitializer<IntegrationProperties.Jdbc> {
/**
* Create a new {@link IntegrationDataSourceScriptDatabaseInitializer} instance.
@ -44,45 +44,7 @@ public class IntegrationDataSourceScriptDatabaseInitializer extends DataSourceSc
*/
public IntegrationDataSourceScriptDatabaseInitializer(DataSource dataSource,
IntegrationProperties.Jdbc properties) {
this(dataSource, getSettings(dataSource, properties));
}
/**
* Create a new {@link IntegrationDataSourceScriptDatabaseInitializer} instance.
* @param dataSource the Spring Integration data source
* @param settings the database initialization settings
* @see #getSettings
*/
public IntegrationDataSourceScriptDatabaseInitializer(DataSource dataSource,
DatabaseInitializationSettings settings) {
super(dataSource, settings);
}
/**
* Adapts {@link IntegrationProperties.Jdbc Spring Integration JDBC properties} to
* {@link DatabaseInitializationSettings} replacing any {@literal @@platform@@}
* placeholders.
* @param dataSource the Spring Integration data source
* @param properties the Spring Integration JDBC properties
* @return a new {@link DatabaseInitializationSettings} instance
* @see #IntegrationDataSourceScriptDatabaseInitializer(DataSource,
* DatabaseInitializationSettings)
*/
static DatabaseInitializationSettings getSettings(DataSource dataSource, IntegrationProperties.Jdbc properties) {
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties));
settings.setMode(properties.getInitializeSchema());
settings.setContinueOnError(true);
return settings;
}
private static List<String> resolveSchemaLocations(DataSource dataSource, IntegrationProperties.Jdbc properties) {
PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver();
platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MARIADB, "mysql");
if (StringUtils.hasText(properties.getPlatform())) {
return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema());
}
return platformResolver.resolveAll(dataSource, properties.getSchema());
super(dataSource, properties, Map.of(DatabaseDriver.MARIADB, "mysql"));
}
}

View File

@ -22,7 +22,7 @@ import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.sql.init.DatabaseInitializationMode;
import org.springframework.boot.jdbc.init.DatabaseInitializationProperties;
/**
* Configuration properties for Spring Integration.
@ -30,6 +30,7 @@ import org.springframework.boot.sql.init.DatabaseInitializationMode;
* @author Vedran Pavic
* @author Stephane Nicoll
* @author Artem Bilan
* @author Yanming Zhou
* @since 2.0.0
*/
@ConfigurationProperties("spring.integration")
@ -212,49 +213,14 @@ public class IntegrationProperties {
}
public static class Jdbc {
public static class Jdbc extends DatabaseInitializationProperties {
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
+ "integration/jdbc/schema-@@platform@@.sql";
/**
* Path to the SQL file to use to initialize the database schema.
*/
private String schema = DEFAULT_SCHEMA_LOCATION;
/**
* Platform to use in initialization scripts if the @@platform@@ placeholder is
* used. Auto-detected by default.
*/
private String platform;
/**
* Database schema initialization mode.
*/
private DatabaseInitializationMode initializeSchema = DatabaseInitializationMode.EMBEDDED;
public String getSchema() {
return this.schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getPlatform() {
return this.platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public DatabaseInitializationMode getInitializeSchema() {
return this.initializeSchema;
}
public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
this.initializeSchema = initializeSchema;
@Override
public String getDefaultSchemaLocation() {
return DEFAULT_SCHEMA_LOCATION;
}
}

View File

@ -55,6 +55,7 @@ import org.springframework.transaction.PlatformTransactionManager;
*
* @author Vedran Pavic
* @author Stephane Nicoll
* @author Yanming Zhou
* @since 2.0.0
*/
@AutoConfiguration(after = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
@ -138,7 +139,7 @@ public class QuartzAutoConfiguration {
DataSource dataSource, @QuartzDataSource ObjectProvider<DataSource> quartzDataSource,
QuartzProperties properties) {
DataSource dataSourceToUse = getDataSource(dataSource, quartzDataSource);
return new QuartzDataSourceScriptDatabaseInitializer(dataSourceToUse, properties);
return new QuartzDataSourceScriptDatabaseInitializer(dataSourceToUse, properties.getJdbc());
}
static class OnQuartzDatasourceInitializationCondition extends OnDatabaseInitializationCondition {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,16 +17,15 @@
package org.springframework.boot.autoconfigure.quartz;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.jdbc.init.PlatformPlaceholderDatabaseDriverResolver;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.boot.jdbc.init.PropertiesBasedDataSourceScriptDatabaseInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* {@link DataSourceScriptDatabaseInitializer} for the Quartz Scheduler database. May be
@ -35,36 +34,25 @@ import org.springframework.util.StringUtils;
* @author Vedran Pavic
* @author Andy Wilkinson
* @author Phillip Webb
* @author Yanming Zhou
* @since 2.6.0
*/
public class QuartzDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer {
public class QuartzDataSourceScriptDatabaseInitializer
extends PropertiesBasedDataSourceScriptDatabaseInitializer<QuartzProperties.Jdbc> {
private final List<String> commentPrefixes;
/**
* Create a new {@link QuartzDataSourceScriptDatabaseInitializer} instance.
* @param dataSource the Quartz Scheduler data source
* @param properties the Quartz properties
* @param properties the Quartz jdbc properties
* @see #getSettings
*/
public QuartzDataSourceScriptDatabaseInitializer(DataSource dataSource, QuartzProperties properties) {
this(dataSource, getSettings(dataSource, properties), properties.getJdbc().getCommentPrefix());
}
/**
* Create a new {@link QuartzDataSourceScriptDatabaseInitializer} instance.
* @param dataSource the Quartz Scheduler data source
* @param settings the database initialization settings
* @see #getSettings
*/
public QuartzDataSourceScriptDatabaseInitializer(DataSource dataSource, DatabaseInitializationSettings settings) {
this(dataSource, settings, null);
}
private QuartzDataSourceScriptDatabaseInitializer(DataSource dataSource, DatabaseInitializationSettings settings,
List<String> commentPrefixes) {
super(dataSource, settings);
this.commentPrefixes = commentPrefixes;
public QuartzDataSourceScriptDatabaseInitializer(DataSource dataSource, QuartzProperties.Jdbc properties) {
super(dataSource, properties,
Map.of(DatabaseDriver.DB2, "db2_v95", DatabaseDriver.MYSQL, "mysql_innodb", DatabaseDriver.MARIADB,
"mysql_innodb", DatabaseDriver.POSTGRESQL, "postgres", DatabaseDriver.SQLSERVER, "sqlServer"));
this.commentPrefixes = properties.getCommentPrefix();
}
@Override
@ -74,35 +62,4 @@ public class QuartzDataSourceScriptDatabaseInitializer extends DataSourceScriptD
}
}
/**
* Adapts {@link QuartzProperties Quartz properties} to
* {@link DatabaseInitializationSettings} replacing any {@literal @@platform@@}
* placeholders.
* @param dataSource the Quartz Scheduler data source
* @param properties the Quartz properties
* @return a new {@link DatabaseInitializationSettings} instance
* @see #QuartzDataSourceScriptDatabaseInitializer(DataSource,
* DatabaseInitializationSettings)
*/
public static DatabaseInitializationSettings getSettings(DataSource dataSource, QuartzProperties properties) {
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties.getJdbc()));
settings.setMode(properties.getJdbc().getInitializeSchema());
settings.setContinueOnError(true);
return settings;
}
private static List<String> resolveSchemaLocations(DataSource dataSource, QuartzProperties.Jdbc properties) {
PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver();
platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.DB2, "db2_v95");
platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MYSQL, "mysql_innodb");
platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MARIADB, "mysql_innodb");
platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.POSTGRESQL, "postgres");
platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.SQLSERVER, "sqlServer");
if (StringUtils.hasText(properties.getPlatform())) {
return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema());
}
return platformResolver.resolveAll(dataSource, properties.getSchema());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,13 +24,14 @@ import java.util.List;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.sql.init.DatabaseInitializationMode;
import org.springframework.boot.jdbc.init.DatabaseInitializationProperties;
/**
* Configuration properties for the Quartz Scheduler integration.
*
* @author Vedran Pavic
* @author Stephane Nicoll
* @author Yanming Zhou
* @since 2.0.0
*/
@ConfigurationProperties("spring.quartz")
@ -131,56 +132,16 @@ public class QuartzProperties {
return this.jdbc;
}
public static class Jdbc {
public static class Jdbc extends DatabaseInitializationProperties {
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/quartz/impl/"
+ "jdbcjobstore/tables_@@platform@@.sql";
/**
* Path to the SQL file to use to initialize the database schema.
*/
private String schema = DEFAULT_SCHEMA_LOCATION;
/**
* Platform to use in initialization scripts if the @@platform@@ placeholder is
* used. Auto-detected by default.
*/
private String platform;
/**
* Database schema initialization mode.
*/
private DatabaseInitializationMode initializeSchema = DatabaseInitializationMode.EMBEDDED;
/**
* Prefixes for single-line comments in SQL initialization scripts.
*/
private List<String> commentPrefix = new ArrayList<>(Arrays.asList("#", "--"));
public String getSchema() {
return this.schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getPlatform() {
return this.platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public DatabaseInitializationMode getInitializeSchema() {
return this.initializeSchema;
}
public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
this.initializeSchema = initializeSchema;
}
public List<String> getCommentPrefix() {
return this.commentPrefix;
}
@ -189,6 +150,11 @@ public class QuartzProperties {
this.commentPrefix = commentPrefix;
}
@Override
public String getDefaultSchemaLocation() {
return DEFAULT_SCHEMA_LOCATION;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,15 +16,13 @@
package org.springframework.boot.autoconfigure.session;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.jdbc.init.PlatformPlaceholderDatabaseDriverResolver;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.util.StringUtils;
import org.springframework.boot.jdbc.init.PropertiesBasedDataSourceScriptDatabaseInitializer;
/**
* {@link DataSourceScriptDatabaseInitializer} for the Spring Session JDBC database. May
@ -34,9 +32,11 @@ import org.springframework.util.StringUtils;
* @author Vedran Pavic
* @author Andy Wilkinson
* @author Phillip Webb
* @author Yanming Zhou
* @since 2.6.0
*/
public class JdbcSessionDataSourceScriptDatabaseInitializer extends DataSourceScriptDatabaseInitializer {
public class JdbcSessionDataSourceScriptDatabaseInitializer
extends PropertiesBasedDataSourceScriptDatabaseInitializer<JdbcSessionProperties> {
/**
* Create a new {@link JdbcSessionDataSourceScriptDatabaseInitializer} instance.
@ -45,45 +45,7 @@ public class JdbcSessionDataSourceScriptDatabaseInitializer extends DataSourceSc
* @see #getSettings
*/
public JdbcSessionDataSourceScriptDatabaseInitializer(DataSource dataSource, JdbcSessionProperties properties) {
this(dataSource, getSettings(dataSource, properties));
}
/**
* Create a new {@link JdbcSessionDataSourceScriptDatabaseInitializer} instance.
* @param dataSource the Spring Session JDBC data source
* @param settings the database initialization settings
* @see #getSettings
*/
public JdbcSessionDataSourceScriptDatabaseInitializer(DataSource dataSource,
DatabaseInitializationSettings settings) {
super(dataSource, settings);
}
/**
* Adapts {@link JdbcSessionProperties Spring Session JDBC properties} to
* {@link DatabaseInitializationSettings} replacing any {@literal @@platform@@}
* placeholders.
* @param dataSource the Spring Session JDBC data source
* @param properties the Spring Session JDBC properties
* @return a new {@link DatabaseInitializationSettings} instance
* @see #JdbcSessionDataSourceScriptDatabaseInitializer(DataSource,
* DatabaseInitializationSettings)
*/
static DatabaseInitializationSettings getSettings(DataSource dataSource, JdbcSessionProperties properties) {
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties));
settings.setMode(properties.getInitializeSchema());
settings.setContinueOnError(true);
return settings;
}
private static List<String> resolveSchemaLocations(DataSource dataSource, JdbcSessionProperties properties) {
PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver();
platformResolver = platformResolver.withDriverPlatform(DatabaseDriver.MARIADB, "mysql");
if (StringUtils.hasText(properties.getPlatform())) {
return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema());
}
return platformResolver.resolveAll(dataSource, properties.getSchema());
super(dataSource, properties, Map.of(DatabaseDriver.MARIADB, "mysql"));
}
}

View File

@ -17,7 +17,7 @@
package org.springframework.boot.autoconfigure.session;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.sql.init.DatabaseInitializationMode;
import org.springframework.boot.jdbc.init.DatabaseInitializationProperties;
import org.springframework.session.FlushMode;
import org.springframework.session.SaveMode;
@ -25,10 +25,11 @@ import org.springframework.session.SaveMode;
* Configuration properties for JDBC backed Spring Session.
*
* @author Vedran Pavic
* @author Yanming Zhou
* @since 2.0.0
*/
@ConfigurationProperties("spring.session.jdbc")
public class JdbcSessionProperties {
public class JdbcSessionProperties extends DatabaseInitializationProperties {
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/"
+ "session/jdbc/schema-@@platform@@.sql";
@ -37,17 +38,6 @@ public class JdbcSessionProperties {
private static final String DEFAULT_CLEANUP_CRON = "0 * * * * *";
/**
* Path to the SQL file to use to initialize the database schema.
*/
private String schema = DEFAULT_SCHEMA_LOCATION;
/**
* Platform to use in initialization scripts if the @@platform@@ placeholder is used.
* Auto-detected by default.
*/
private String platform;
/**
* Name of the database table used to store sessions.
*/
@ -58,11 +48,6 @@ public class JdbcSessionProperties {
*/
private String cleanupCron = DEFAULT_CLEANUP_CRON;
/**
* Database schema initialization mode.
*/
private DatabaseInitializationMode initializeSchema = DatabaseInitializationMode.EMBEDDED;
/**
* Sessions flush mode. Determines when session changes are written to the session
* store.
@ -75,22 +60,6 @@ public class JdbcSessionProperties {
*/
private SaveMode saveMode = SaveMode.ON_SET_ATTRIBUTE;
public String getSchema() {
return this.schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getPlatform() {
return this.platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getTableName() {
return this.tableName;
}
@ -107,14 +76,6 @@ public class JdbcSessionProperties {
this.cleanupCron = cleanupCron;
}
public DatabaseInitializationMode getInitializeSchema() {
return this.initializeSchema;
}
public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
this.initializeSchema = initializeSchema;
}
public FlushMode getFlushMode() {
return this.flushMode;
}
@ -131,4 +92,9 @@ public class JdbcSessionProperties {
this.saveMode = saveMode;
}
@Override
public String getDefaultSchemaLocation() {
return DEFAULT_SCHEMA_LOCATION;
}
}

View File

@ -81,6 +81,7 @@ import static org.mockito.Mockito.mock;
* @author Vedran Pavic
* @author Stephane Nicoll
* @author Andy Wilkinson
* @author Yanming Zhou
*/
@ExtendWith(OutputCaptureExtension.class)
class QuartzAutoConfigurationTests {
@ -556,7 +557,7 @@ class QuartzAutoConfigurationTests {
@Bean
QuartzDataSourceScriptDatabaseInitializer customInitializer(DataSource dataSource,
QuartzProperties properties) {
return new QuartzDataSourceScriptDatabaseInitializer(dataSource, properties);
return new QuartzDataSourceScriptDatabaseInitializer(dataSource, properties.getJdbc());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -33,6 +33,7 @@ import static org.mockito.Mockito.mock;
* Tests for {@link QuartzDataSourceScriptDatabaseInitializer}.
*
* @author Stephane Nicoll
* @author Yanming Zhou
*/
class QuartzDataSourceScriptDatabaseInitializerTests {
@ -42,7 +43,7 @@ class QuartzDataSourceScriptDatabaseInitializerTests {
QuartzProperties properties = new QuartzProperties();
properties.getJdbc().setPlatform("test");
DatabaseInitializationSettings settings = QuartzDataSourceScriptDatabaseInitializer.getSettings(dataSource,
properties);
properties.getJdbc());
assertThat(settings.getSchemaLocations())
.containsOnly("classpath:org/quartz/impl/jdbcjobstore/tables_test.sql");
then(dataSource).shouldHaveNoInteractions();
@ -54,7 +55,7 @@ class QuartzDataSourceScriptDatabaseInitializerTests {
properties.getJdbc().setPlatform("test");
properties.getJdbc().setCommentPrefix(Arrays.asList("##", "--"));
QuartzDataSourceScriptDatabaseInitializer initializer = new QuartzDataSourceScriptDatabaseInitializer(
mock(DataSource.class), properties);
mock(DataSource.class), properties.getJdbc());
ResourceDatabasePopulator populator = mock(ResourceDatabasePopulator.class);
initializer.customize(populator);
then(populator).should().setCommentPrefixes("##", "--");

View File

@ -0,0 +1,85 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.jdbc.init;
import org.springframework.boot.sql.init.DatabaseInitializationMode;
/**
* Base configuration properties class for performing SQL database initialization.
*
* @author Yanming Zhou
* @since 4.0.0
*/
public abstract class DatabaseInitializationProperties {
/**
* Path to the SQL file to use to initialize the database schema.
*/
private String schema = getDefaultSchemaLocation();
/**
* Platform to use in initialization scripts if the @@platform@@ placeholder is used.
* Auto-detected by default.
*/
private String platform;
/**
* Database schema initialization mode.
*/
private DatabaseInitializationMode initializeSchema = DatabaseInitializationMode.EMBEDDED;
/**
* Whether initialization should continue when an error occurs when applying a schema
* script.
*/
private boolean continueOnError = true;
public String getSchema() {
return this.schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getPlatform() {
return this.platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public DatabaseInitializationMode getInitializeSchema() {
return this.initializeSchema;
}
public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
this.initializeSchema = initializeSchema;
}
public boolean isContinueOnError() {
return this.continueOnError;
}
public void setContinueOnError(boolean continueOnError) {
this.continueOnError = continueOnError;
}
public abstract String getDefaultSchemaLocation();
}

View File

@ -0,0 +1,107 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.jdbc.init;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.util.StringUtils;
/**
* Convenience class for construct {@link DataSourceScriptDatabaseInitializer} base on
* {@link DatabaseInitializationProperties}.
*
* @param <T> the {@link DatabaseInitializationProperties} type being used
* @author Yanming Zhou
* @since 4.0.0
*/
public class PropertiesBasedDataSourceScriptDatabaseInitializer<T extends DatabaseInitializationProperties>
extends DataSourceScriptDatabaseInitializer {
/**
* Create a new {@link PropertiesBasedDataSourceScriptDatabaseInitializer} instance.
* @param dataSource the data source
* @param properties the configuration properties
* @see #getSettings
*/
public PropertiesBasedDataSourceScriptDatabaseInitializer(DataSource dataSource, T properties) {
this(dataSource, properties, Collections.emptyMap());
}
/**
* Create a new {@link PropertiesBasedDataSourceScriptDatabaseInitializer} instance.
* @param dataSource the data source
* @param properties the configuration properties
* @param driverMappings the driver mappings
* @see #getSettings
*/
public PropertiesBasedDataSourceScriptDatabaseInitializer(DataSource dataSource, T properties,
Map<DatabaseDriver, String> driverMappings) {
super(dataSource, getSettings(dataSource, properties, driverMappings));
}
/**
* Adapts {@link DatabaseInitializationProperties configuration properties} to
* {@link DatabaseInitializationSettings} replacing any {@literal @@platform@@}
* placeholders.
* @param dataSource the data source
* @param properties the configuration properties
* @param <T> the {@link DatabaseInitializationProperties} type being used
* @return a new {@link DatabaseInitializationSettings} instance
*/
public static <T extends DatabaseInitializationProperties> DatabaseInitializationSettings getSettings(
DataSource dataSource, T properties) {
return getSettings(dataSource, properties, Collections.emptyMap());
}
/**
* Adapts {@link DatabaseInitializationProperties configuration properties} to
* {@link DatabaseInitializationSettings} replacing any {@literal @@platform@@}
* placeholders.
* @param dataSource the data source
* @param properties the configuration properties
* @param driverMappings the driver mappings
* @param <T> the {@link DatabaseInitializationProperties} type being used
* @return a new {@link DatabaseInitializationSettings} instance
*/
public static <T extends DatabaseInitializationProperties> DatabaseInitializationSettings getSettings(
DataSource dataSource, T properties, Map<DatabaseDriver, String> driverMappings) {
DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties, driverMappings));
settings.setMode(properties.getInitializeSchema());
settings.setContinueOnError(properties.isContinueOnError());
return settings;
}
private static <T extends DatabaseInitializationProperties> List<String> resolveSchemaLocations(
DataSource dataSource, T properties, Map<DatabaseDriver, String> driverMappings) {
PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver();
for (Map.Entry<DatabaseDriver, String> entry : driverMappings.entrySet()) {
platformResolver = platformResolver.withDriverPlatform(entry.getKey(), entry.getValue());
}
if (StringUtils.hasText(properties.getPlatform())) {
return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema());
}
return platformResolver.resolveAll(dataSource, properties.getSchema());
}
}