比如我要初始化一个系统管理员
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();
}
}
注意:
若要初始化多个脚本,增加脚本文件即可,要注意顺序