问题
I am developing a spring boot application. At the moment some of my configs are hard coded (e.g. Hystrix properties).
So I would like to get these configs on my application start up time or just after that.
Is it possible to do that using spring boot? I mean to run SQL script on start up and get data.
How should properties/configs be retrieved and stored in my application?
I am using MyBatis and Oracle DB.
回答1:
By default, Spring-Boot loads data.sql
and/or data-${platform}.sql
.
However, keep in mind that the script would be loaded at every start, so I would think it makes more sense (at least for production), to just have the values already present in the database, not re-inserted at every start. I've personally only used database initialization for test/dev purposes when using a memory database. Still, this is the feature provided by Spring-Boot.
source: spring-boot-howto-database-initialization:
Spring JDBC has a DataSource initializer feature. Spring Boot enables it by default and loads SQL from the standard locations schema.sql and data.sql (in the root of the classpath). In addition Spring Boot will load the schema-${platform}.sql and data-${platform}.sql files (if present).
src/main/resources/data-oracle.sql:
insert into...
insert into...
- You may define the platform with:
spring.datasource.platform=oracle
. - You may change the name of the sql script to load with:
spring.datasource.data=myscript.sql
. - Along with
data.sql
, Spring-boot also loadsschema.sql
(beforedata.sql
). - You could also have an "update or insert" logic in your data.sql: oracle sql: update if exists else insert
回答2:
If you want to insert data based on some business logic I would recommend you to have Event Listener. So basically on application startup "OnApplicationEvent" as it is annotated with @EventListener method will be called automatically.
Also as in your case you need to get the data, you simply use your repository object to get the data as well.
Here's one example:
@Component
public class OnApplicationStartUp {
@Autowired
private ServiceRepository repository;
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
//Write your business logic here.
if (repository.findAll().size() <= 0) {
preloadData();
}else{
fetchData();
}
}
private void preloadData() {
List<Service> services = new ArrayList<>();
Service someService= new Service("name", "type");
services.add(someService);
...
...
repository.saveAll(services);
}
}
回答3:
If you getting from application.properties file you can use Environment class. Like that
Autowired
private Environment environment;
...
environment.getProperty("propertyName")
or you can define your own property file. then you can get from it with
@PropertySource(name = "myProperties", value = "example.properties")
annotation
You need to use @Value annotation to get a specific value from the property file which you defined.
@Value("${propertyNameInYourPropertFile}")
private String url;
And You want to start something when Application is just started, you can use this before a method
@EventListener(ApplicationReadyEvent.class)
But need to use @Service or @Component Annotation, which Class has the method.
Totally, You can use this.
example.properties :
url=yourValue
userName=yourDBUserName
password=yourDBPassword
example class :
@Service
@PropertySource(name = "myProperties", value = "example.properties")
public class Start{
@Value("${url}")
private String url;
@Value("${userName}")
private String userName;
@Value("${password}")
private String password;
//Run this method when application started
@EventListener(ApplicationReadyEvent.class)
public ResultSet getConnection()
{
//Connect to Database
Connection connection = null;
String QUERY="your sql query";
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
connection = DriverManager.getConnection(url, userName, password );
} catch (SQLException e) {
}
//Run your query
Statement stmt = null;
try {
stmt = connection.createStatement();
} catch (SQLException e1) {
e1.printStackTrace();
}
ResultSet rs = null;
try {
rs = stmt.executeQuery(QUERY);
} catch (SQLException e1) {
e1.printStackTrace();
}
return rs;
}
}
回答4:
What worked for me is using DataSourceInitializer
:
@Bean
public DataSourceInitializer dataSourceInitializer(@Qualifier("dataSource") 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;
}
Used to set up a database during initialization and clean up a database during destruction.
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/datasource/init/DataSourceInitializer.html
来源:https://stackoverflow.com/questions/39280340/spring-boot-run-sql-scripts-and-get-data-on-application-startup