项目启动初始化SQL脚本

比如我要初始化一个系统管理员

1.需要先检查这个用户是否存在,若存在则不执行插入用户的sql脚本

需要将检查的sql语句放在配置文件中

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.如果不存在就执行插入用户的sql文件中的sql语句,把需要初始化的sql脚本文件,放在resource资源文件夹中,名称要和配置文件中的key名称一致

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.然后还需要一个检查sql的配置类来管理检查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.还需要一个项目运行的配置类来管理和保证数据初始化的工作

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

注意:

若要初始化多个脚本,增加脚本文件即可,要注意顺序

猜你喜欢

转载自blog.csdn.net/weixin_43650254/article/details/118889179