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

sf6xfgos  于 2022-12-28  发布在  Spring
关注(0)|答案(7)|浏览(176)

我正在开发一个Sping Boot 应用程序。目前我的一些配置是硬编码的(Eidogg. Hystrix属性)。
因此,我希望在应用程序启动时或启动后获得这些配置。
有没有可能使用Sping Boot 来实现呢?我的意思是在启动时运行SQL脚本并获取数据。
应该如何在我的应用程序中检索和存储属性/配置?
我正在使用MyBatis和Oracle数据库。

lzfw57am

lzfw57am1#

默认情况下,Spring-Boot加载data.sql和/或data-${platform}.sql
但是,请记住,脚本将在每次启动时加载,因此我认为更有意义的做法(至少对于生产)是,只将值存在于数据库中,而不是在每次启动时重新插入。**我个人在使用内存数据库时,仅将数据库初始化用于测试/开发目的。**不过,这是Spring-Boot提供的特性。
来源:spring-boot-howto-database-initialization
Spring JDBC具有数据源初始化器特性。Spring Boot默认启用该特性,并从标准位置schema.sql和data.sql(在类路径的根目录中)加载SQL。此外,Spring Boot将加载schema-${platform}. sql和data-${platform}. sql文件(如果存在)。
源代码/主/资源/数据-oracle. 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中使用"更新或插入"逻辑:oracle sql: update if exists else insert
wnavrhmk

wnavrhmk2#

对我有效的方法是使用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;
}

用于在初始化期间设置数据库,并在销毁期间清除数据库。
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/datasource/init/DataSourceInitializer.html

mo49yndu

mo49yndu3#

如果要在启动后从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语句,因为它会被忽略。

ohfgkhjo

ohfgkhjo4#

如果你想根据一些业务逻辑插入数据,我建议你使用事件监听器。所以基本上,在应用程序启动时,"OnApplicationEvent"会被自动调用,因为它是用@EventListener方法注解的。
同样,在您需要获取数据的情况下,也可以简单地使用存储库对象来获取数据。
下面是一个例子:

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

x759pob25#

If you getting from application.properties file you can use Environment class. Like that

Autowired
private Environment environment;
...
environment.getProperty("propertyName")

或者你可以定义你自己的属性文件.然后你可以用@PropertySource(name = "myProperties", value = "example.properties")注解从它获取
您需要使用@Value注解从您定义的属性文件中获取特定值。

@Value("${propertyNameInYourPropertFile}")
private String url;

如果你想在应用程序刚启动的时候启动一些东西,你可以在方法之前使用这个

@EventListener(ApplicationReadyEvent.class)

但需要使用@Service或@Component Annotation,该类具有该方法。
当然,你可以用这个。
example.properties :

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

}
qnzebej0

qnzebej06#

1.定义Spring Bean(例如,全局配置Bean)
作用域为:@Scope(作用域名称= Web应用程序上下文.SCOPE_APPLICATION)
此Bean将负责在Bean初始化期间从数据库表中获取数据(维护配置属性)。
1.使用@PostConstruct注解方法。
此方法将具有从数据库表中获取配置参数的逻辑。
1.此bean的作用域将确保所需配置仅从数据库表中提取一次(例如,使用Hibernate查询或纯原生SQL),并且
可用于同一应用程序中不同上下文的所有bean。
现在,只要在您希望使用那些配置属性或参数的任何地方注入这个bean。

用途::Apache共享数据库配置〈--
注意::它不支持缓存。但我猜你不需要缓存,因为数据库配置属性应该只加载一次,在应用程序启动的开始。

传统老办法:通过扩展定义“PropertyPlaceHolderConfigurer”的自定义实现,并将其定义为SpringBean。
这个实现应该具有从数据库表中获取数据的逻辑,该数据库表保存配置属性。

f4t66c6m

f4t66c6m7#

Initialize Database(Execute schema.sql and data.sql) using JDBC in spring boot 

Note: Follow these steps 
   
       1. create sample project 
          pom.xml (edit it based on your version)
            
                <?xml version="1.0" encoding="UTF-8"?>
            <project xmlns="http://maven.apache.org/POM/4.0.0"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
                <modelVersion>4.0.0</modelVersion>
                <parent>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-parent</artifactId>
                    <version>3.0.1</version>
                    <relativePath /> <!-- lookup parent from repository -->
                </parent>
                <groupId>com.example</groupId>
                <artifactId>Init_Sql_Script</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <name>Init_Sql_Script</name>
                <description>Initialize a Database Using Basic SQL Scripts</description>
                <properties>
                    <java.version>17</java.version>
                </properties>
                <dependencies>
            
                    <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-jdbc</artifactId>
                    </dependency>
            
                    <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-web</artifactId>
                    </dependency>
            
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <scope>runtime</scope>
                    </dependency>
            
                    <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-test</artifactId>
                        <scope>test</scope>
                    </dependency>
                </dependencies>
            
                <build>
                    <plugins>
                        <plugin>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-maven-plugin</artifactId>
                        </plugin>
                    </plugins>
                </build>
            
            </project>
            
            
         2.  application properties && create new db name like employee in ur DB
        
            # connection code for spring boot to your DB
            spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
            spring.datasource.url=jdbc:mysql://localhost:3306/employee
            spring.datasource.username=Hari
            spring.datasource.password=1998
            
            spring.jpa.hibernate.ddl-auto=none
            
            #--- control the sql db initialization (from schema.sql and data.sql)---
            spring. SQL.init.mode=always
            
            
            #---if any error it skips the script and executes the next script----
            #spring.sql.init.continue-on-error=true
            
         3.  create two SQL files (schema.sql-create table query and data.sql-insert query) in the resource folder 
         4. run the application after that check db thats all Try it.
     its working for me I Hope its working for u also

相关问题