Project startup initialization SQL script

For example, I want to initialize a system administrator

1. You need to check whether the user exists first, and if it exists, the sql script for inserting the user will not be executed

The checked sql statement needs to be placed in the configuration file

sql:
  init:
    checksql:
      "1-sys_user-DML": "select case when exists(select 1 from sys_user su where su.login_name='admin') then 1 else 0 end as result from dual"

2. If it does not exist, execute the sql statement inserted into the user's sql file, put the sql script file that needs to be initialized in the resource resource folder, and the name should be consistent with the key name in the configuration file

sql/init/1-sys_user-DML.sql

INSERT INTO sys_user (id, login_name, credential_value, user_type, deleted, gmt_creare, gmt_modified) VALUES (1409695958421741550, 'admin', '7a6746bdbda9c1a662ceba4ec05b0721', 1, 0, NOW(), NOW());

3. Then you need a configuration class for checking sql to manage checking sql

package cn.gt.authoritycenter.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName SqlInitCheckSqlConfig
 * @Description: 初始化Sql用配置类
 * @Author Jason
 * @Date 2021/6/7
 **/
@Component
@ConfigurationProperties(prefix = "sql.init")
public class SqlInitCheckSqlConfig {
    
    

    private Map<String, String> checksql = new HashMap();

    public Map<String, String> getChecksql() {
    
    
        return checksql;
    }

    public void setChecksql(Map<String, String> checksql) {
    
    
        this.checksql = checksql;
    }

    @Override
    public String toString() {
    
    
        return "SqlInitCheckSqlConfig{" +
                "checksql=" + checksql +
                '}';
    }
}

4. A configuration class for project operation is also required to manage and ensure the work of data initialization

package cn.gt.authoritycenter.config;

import org.eclipse.jetty.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.lang.NonNull;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

/**
 * @ClassName InitSqlConfig
 * @Description: 项目运行初始化数据
 * @Author Jason
 * @Date 2021/6/4
 **/
@Configuration
public class InitSqlConfig {
    
    

    private final Logger logger = LoggerFactory.getLogger(InitSqlConfig.class);

    @Autowired
    private SqlInitCheckSqlConfig sqlInitCheckSqlConfig;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Bean
    public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) throws IOException {
    
    
        final DataSourceInitializer initializer = new DataSourceInitializer();
        initializer.setDataSource(dataSource);
        initializer.setDatabasePopulator(this.databasePopulator());
        return initializer;
    }

    /**
     * 初始化数据策略
     *
     * @author ljs
     * @exception IOException
     */
    private DatabasePopulator databasePopulator() throws IOException {
    
    
        final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        populator.addScripts(this.getResources());
        return populator;
    }

    /**
     * 初始化数据资源
     *
     * @author ljs
     * @exception IOException
     */
    private Resource[] getResources() throws IOException {
    
    
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("classpath*:sql/init/*.sql");
        List<Resource> resultList = new LinkedList<>();
        //"加载初始化脚本文件---------start"
        String checkSqlStr;
        Integer resutlNum;
        String dqlSqlMatch = "";
        int n = 0;
        for (Resource resource : resources) {
    
    
            String fileFullName = resource.getFilename();
            // 如果DQL语句都没有执行,则默认要执行DML语句
            /*if (fileFullName.matches(".*DML.*") && StringUtil.isNotBlank(dqlSqlMatch)
                    && fileFullName.matches(dqlSqlMatch)) {
                resultList.add(resource);
                continue;
            }*/
            // 获得验证脚本
            checkSqlStr = this.getCheckSql(fileFullName);
            if (StringUtil.isNotBlank(checkSqlStr)) {
    
    
                resutlNum = jdbcTemplate.queryForObject(checkSqlStr, Integer.class);
                if (resutlNum != null && resutlNum == 0) {
    
    
                    resultList.add(resource);
                    if (fileFullName.matches(".*DML.*")) {
    
    
                        logger.trace("sql初始化脚本文件[{}]验证结果为0,执行该脚本", fileFullName);
                        dqlSqlMatch += this.buildDqlSqlMatch(fileFullName, dqlSqlMatch);
                    }
                } else {
    
    
                    logger.trace("sql初始化脚本文件[{}]验证结果为1,跳过该脚本", fileFullName);
                }
            }
        }
        //"加载初始化脚本文件---------end"
        return resultList.toArray(new Resource[0]);
    }

    /**
     * 获取去掉后缀的文件名
     *
     * @author ljs
     * @param fileFullName
     *            资源文件全名
     * @return java.lang.String 文件名
     */
    private String getCheckSql(@NonNull String fileFullName) {
    
    
        String fileName = fileFullName.replace(".sql", "");
        String checkSqlStr = sqlInitCheckSqlConfig.getChecksql().get(fileName);
        if (StringUtil.isBlank(checkSqlStr)) {
    
    
            logger.trace("sql脚本文件[{}.sql]的执行验证语句未配置~~~~~不执行该SQL脚本", fileName);
        }
        return checkSqlStr;
    }

    /**
     * 构建DQL语句匹配规则
     *
     * @author ljs
     * @param fileFullName
     *            全文件名
     * @param dqlSqlMatch
     *            DQL语句匹配规则
     * @return java.lang.String 构建结果
     */
    private String buildDqlSqlMatch(String fileFullName, String dqlSqlMatch) {
    
    
        String[] fileFullNameSplit = fileFullName.split("-");
        StringBuilder sb = new StringBuilder();
        if (StringUtil.isBlank(dqlSqlMatch)) {
    
    
            sb.append(".*\\-");
        } else {
    
    
            sb.append("|.*\\-");
        }
        sb.append(fileFullNameSplit[1]);
        sb.append("\\-.*");
        return sb.toString();
    }
}

Notice:

To initialize multiple scripts, just add script files, pay attention to the order

Guess you like

Origin blog.csdn.net/weixin_43650254/article/details/118889179