Spring 執行 sql 腳本(文件)

本篇解決 Spring 執行SQL腳本(文件)的問題。java

場景描述能夠不看。git

場景描述:github

我在運行單測的時候,也就是 Spring 工程啓動的時候,Spring 會去執行 classpath:schema.sql(後面會解釋),我想利用這一點,解決一個問題:spring

一次運行多個測試文件,每一個文件前後獨立運行,而上一個文件建立的數據,會對下一個文件運行時形成影響,因此我要在每一個文件執行完成以後,重置數據庫,不僅僅是把數據刪掉,而 schema.sql 裏面有 drop table 和create table。sql

解決方法:數據庫

//Schema 處理器
@Component
public class SchemaHandler {
    private final String SCHEMA_SQL = "classpath:schema.sql";
    @Autowired
    private DataSource datasource;
    @Autowired
    private SpringContextGetter springContextGetter;

    public void execute() throws Exception {
        Resource resource = springContextGetter.getApplicationContext().getResource(SCHEMA_SQL);
        ScriptUtils.executeSqlScript(datasource.getConnection(), resource);
    }
}

// 獲取 ApplicationContext
@Component
public class SpringContextGetter implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}

備註:app

關於爲什麼 Spring 會去執行 classpath:schema.sql,能夠參考源碼ide

org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer#runSchemaScriptsspring-boot

private void runSchemaScripts() {
        List<Resource> scripts = getScripts("spring.datasource.schema",
                this.properties.getSchema(), "schema");
        if (!scripts.isEmpty()) {
            String username = this.properties.getSchemaUsername();
            String password = this.properties.getSchemaPassword();
            runScripts(scripts, username, password);
            try {
                this.applicationContext
                        .publishEvent(new DataSourceInitializedEvent(this.dataSource));
                // The listener might not be registered yet, so don't rely on it.
                if (!this.initialized) {
                    runDataScripts();
                    this.initialized = true;
                }
            }
            catch (IllegalStateException ex) {
                logger.warn("Could not send event to complete DataSource initialization ("
                        + ex.getMessage() + ")");
            }
        }
    }

/**
 * 默認拿 classpath*:schema-all.sql 和 classpath*:schema.sql
 */
private List<Resource> getScripts(String propertyName, List<String> resources,
            String fallback) {
        if (resources != null) {
            return getResources(propertyName, resources, true);
        }
        String platform = this.properties.getPlatform();
        List<String> fallbackResources = new ArrayList<String>();
        fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");
        fallbackResources.add("classpath*:" + fallback + ".sql");
        return getResources(propertyName, fallbackResources, false);
    }

參考:https://github.com/spring-pro...測試

原文連接:
http://zhige.me/2019/02/28/20...

相關文章
相關標籤/搜索