Java 如何在应用程序启动时运行SQL脚本并获取数据?

Java 如何在应用程序启动时运行SQL脚本并获取数据?,java,sql,spring,spring-boot,sql-scripts,Java,Sql,Spring,Spring Boot,Sql Scripts,我正在开发一个Spring启动应用程序。目前,我的一些配置是硬编码的(例如Hystrix属性) 因此,我希望在应用程序启动时或之后获得这些配置 使用Spring Boot可以做到这一点吗?我的意思是在启动时运行SQL脚本并获取数据 如何在我的应用程序中检索和存储属性/配置 我正在使用MyBatis和Oracle DB。默认情况下,Spring引导加载data.sql和/或data-${platform}.sql 但是,请记住,脚本将在每次启动时加载,因此我认为更合理的做法(至少对于生产而言)是将

我正在开发一个Spring启动应用程序。目前,我的一些配置是硬编码的(例如Hystrix属性)

因此,我希望在应用程序启动时或之后获得这些配置

使用Spring Boot可以做到这一点吗?我的意思是在启动时运行SQL脚本并获取数据

如何在我的应用程序中检索和存储属性/配置


我正在使用MyBatis和Oracle DB。

默认情况下,Spring引导加载
data.sql
和/或
data-${platform}.sql

但是,请记住,脚本将在每次启动时加载,因此我认为更合理的做法(至少对于生产而言)是将值已经存在于数据库中,而不是在每次启动时重新插入在使用内存数据库时,我个人仅将数据库初始化用于测试/开发目的。不过,这是Spring Boot提供的功能

资料来源:

SpringJDBC具有数据源初始值设定项功能。弹簧启动启用 默认情况下,它会从标准位置schema.SQL和 data.sql(在类路径的根目录中)。此外,弹簧靴将 加载模式-${platform}.sql和数据-${platform}.sql文件(如果需要) 现在)

src/main/resources/dataoracle.sql:

insert into...
insert into...
  • 您可以使用以下命令定义平台:
    spring.datasource.platform=oracle
  • 您可以更改要加载的sql脚本的名称:
    spring.datasource.data=myscript.sql
  • 除了
    data.sql
    ,Spring boot还加载
    schema.sql
    (在
    data.sql
    之前)
  • 您还可以在data.sql中使用“更新或插入”逻辑:

如果您希望插入基于某些业务逻辑的数据,我建议您使用事件侦听器。因此,基本上在应用程序启动时,将自动调用用@EventListener方法注释的“OnApplicationEvent”

同样,在您需要获取数据的情况下,您只需使用存储库对象来获取数据

这里有一个例子:

@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);
   }
}
@组件
应用程序启动时的公共类{
@自动连线
私有服务存储库;
@事件监听器
ApplicationEvent(ContextRefreshedEvent事件)上的公共无效{
//在这里写下您的业务逻辑。

if(repository.findAll().size()如果从application.properties文件中获取,则可以使用环境类。 那样

Autowired
private Environment environment;
...
environment.getProperty("propertyName")
或者您可以定义自己的属性文件。然后您可以使用
@PropertySource(name=“myProperties”,value=“example.properties”)
注释

您需要使用@Value annotation从定义的属性文件中获取特定值

@Value("${propertyNameInYourPropertFile}")
private String url;
当应用程序刚刚启动时,您想启动一些东西,可以在方法之前使用它

@EventListener(ApplicationReadyEvent.class)
但是需要使用@Service或@Component注释,哪个类有这个方法

完全可以用这个

示例.属性:

url=yourValue
userName=yourDBUserName
password=yourDBPassword
示例类:

@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;
    }

}

对我有效的方法是使用
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;
}
用于在初始化期间设置数据库并清理 数据库在销毁过程中

  • 定义SpringBean(例如GlobalConfiguration Bean)
    范围:@Scope(scopeName=WebApplicationContext.Scope\u应用程序)
    这个Bean将负责在Bean初始化期间从数据库表中获取数据(维护配置属性)

  • 使用@PostConstruct注释方法。
    此方法具有从数据库表获取配置参数的逻辑

  • 此bean的作用域将确保只从数据库表获取一次所需的配置(例如,使用Hibernate查询或纯本机SQL),并且
    可用于同一应用程序中不同上下文的所有bean

  • 现在只要在您希望使用这些配置属性或参数的任何地方注入这个bean即可。



    用法::Apache Commons数据库配置

    当仅使用基本SQL脚本时,Spring Boot会自动创建嵌入式数据源的架构。可以使用Spring.DataSource.initialization-mode属性自定义此行为。例如,如果希望始终初始化数据源,而不管其类型如何:

    spring.datasource.initialization-mode=always
    

    如果要在启动后从sql脚本加载数据,请使用ResourceDatabasePopulator类对象,如下所示

    import org.springframework.boot.context.event.ApplicationReadyEvent;
    import org.springframework.context.event.EventListener;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
    
    import javax.sql.DataSource;
    
    @Component
    public class InitializeData {
    
        @Autowired
        private DataSource dataSource;
    
        @EventListener(ApplicationReadyEvent.class)
        public void loadData() {
                ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator(false, false, "UTF-8", new ClassPathResource("data.sql"));
            resourceDatabasePopulator.execute(dataSource);
        }
    }
    

    它可以轻松地从sql文件加载数据,并且不必担心sql文件中的错误sql语句会被忽略。

    将它们放在application.yml中。使它们依赖于配置文件。我有这样的想法,但目前我想从DB中获取值:)我不需要插入数据。我需要从数据库获取数据:)看看spring batch是如何工作的,启动时不需要运行select命令..看不出目的..如果你想在启动时加载数据,最好使用批处理easy@LaurynasHello@alexbt该用户发布的标题有点误导。他希望加载配置f在应用程序启动时rom数据库(而不是创建和初始化模式).p.s.要加载自定义文件名,您可以设置
    spring.datasource.schema
    仅限代码的答案。请单击“编辑”并添加一些文字,概述您的代码如何解决问题,或者解释您的答案与以前的答案有何不同。感谢该用户发布的标题有点误导。他希望s在应用程序启动时从数据库加载配置(而不是创建和初始化架构)。@PhilipDilip此解决方案可用于执行脚本,而不仅仅用于初始化架构。