package com.yuanchu.mom.backup;
|
|
import com.yuanchu.mom.dto.PerformanceShiftAddDto;
|
import com.yuanchu.mom.mapper.EnumMapper;
|
import com.yuanchu.mom.pojo.Enums;
|
import com.yuanchu.mom.pojo.PerformanceShift;
|
import com.yuanchu.mom.pojo.User;
|
import com.yuanchu.mom.service.EnumService;
|
import com.yuanchu.mom.service.PerformanceShiftService;
|
import com.yuanchu.mom.service.UserService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Component;
|
|
import javax.annotation.Resource;
|
import java.io.*;
|
import java.text.SimpleDateFormat;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.LocalTime;
|
import java.time.temporal.TemporalAdjusters;
|
import java.time.temporal.WeekFields;
|
import java.util.Date;
|
import java.util.Dictionary;
|
import java.util.List;
|
import java.util.Locale;
|
import java.util.stream.Collectors;
|
|
@Component
|
@EnableScheduling
|
@Slf4j
|
public class MysqlDataBackup {
|
/**
|
* 数据库版本是否为 8.0 + (false=否 true=是), mysql8+ 需要参数 --column-statistics=0 , mysql8- 不需要
|
*/
|
Boolean isDbVersion8 = false;
|
|
/**
|
* 备份命令
|
* USERNAME 账号
|
* PASSWORD 密码
|
* SERVERPATH 服务器IP/域名
|
* DBNAME 数据库名称
|
* FILEPATH 备份文件存放地址+名称
|
* 说明
|
* cmdCompression : 需压缩 (本地或服务器需安装 mysqldump 命令(安装mysql自带患独立安装) + gzip 命令(独立安装))
|
* cmd : 不压缩 (本地或服务器需安装 mysqldump 命令(安装mysql自带患独立安装)
|
* --column-statistics=0 mysql8 添加该参数, 非mysql8 不添加, 否则将出错
|
*/
|
String cmdMysql8 = "mysqldump --column-statistics=0 -u{USERNAME} -p{PASSWORD} -h{SERVERPATH} -P3306 --databases {DBNAME}"; // > {FILEPATH}.sql
|
String cmd = "mysqldump -u{USERNAME} -p{PASSWORD} -h{SERVERPATH} -P3306 --databases {DBNAME}"; // > {FILEPATH}.sql
|
|
/**
|
* 备份 sql 存放目录(相对路径, 注意可能需要在 MvcConfig 配置访问权限)
|
*/
|
@Value("${backup.path}")
|
private String filePath;
|
|
@Value("${spring.datasource.url}")
|
private String dbUrl;
|
|
@Value("${spring.datasource.username}")
|
private String dbUserName;
|
|
@Value("${spring.datasource.password}")
|
private String dbPassWord;
|
|
@Value("${backup.destiny}")
|
private Integer destiny;
|
|
@Value("${backup.mysqldump}")
|
private String mysqldump;
|
|
@Resource
|
private PerformanceShiftService performanceShiftService;
|
|
@Resource
|
private EnumService enumService;
|
|
@Resource
|
private UserService userService;
|
|
/**
|
* 每天晚上23点05秒执行 【 0 0 4 1/1 * ? 】
|
* 测试 20 秒一次【 0/20 * * * * ? 】@Scheduled(cron = "5 * 23 * * ?")
|
*/
|
//@Scheduled(cron = "0/20 * * * * ?")
|
private void configureTasks() {
|
log.info("【备份数据库】--START");
|
String dbUrl2 = dbUrl.replace("jdbc:mysql://", "");
|
|
// 获取数据库名称
|
String dbName = dbUrl2.substring(dbUrl2.lastIndexOf("/") + 1, dbUrl2.indexOf("?"));
|
// 获取数据库地址
|
String serverPath = dbUrl2.substring(0, dbUrl2.lastIndexOf(":"));
|
// 数据库账号
|
String username = dbUserName;
|
// 数据库密码
|
String password = dbPassWord;
|
|
// 备份文件目录+名称 备份文件存放目录+名称(名称 = 数据库名+时间字符串.sql)
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
String format = simpleDateFormat.format(new Date());
|
String timeStr = format
|
.replaceAll("-", "_")
|
.replaceAll(" ", "_")
|
.replaceAll(":", "");
|
timeStr = timeStr.substring(0, 15);
|
String pathFileName = filePath + "/" + dbName + "_" + timeStr + ".sql";
|
String newCmd = "";
|
if (isDbVersion8) {
|
newCmd = cmdMysql8;
|
} else {
|
newCmd = cmd;
|
}
|
// 执行命令
|
newCmd = newCmd.replace("{USERNAME}", username)
|
.replace("{PASSWORD}", password)
|
.replace("{SERVERPATH}", serverPath)
|
.replace("{DBNAME}", dbName)
|
.replace("{FILEPATH}", pathFileName);
|
PrintWriter printWriter = null;
|
BufferedReader bufferedReader = null;
|
try {
|
// 创建存放sql的文件
|
existsFile(new File(pathFileName));
|
printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(pathFileName), "utf8"));
|
Process process = null;
|
String property = System.getProperty("os.name");
|
System.out.println(property);
|
if (property.indexOf("Linux") != -1) {
|
// linux
|
process = Runtime.getRuntime().exec(new String[]{"bash", "-c", newCmd});
|
} else {
|
// 本地win
|
String mysqldumpPath = "cmd /c " + mysqldump + "/" + newCmd;
|
System.out.println(mysqldumpPath);
|
process = Runtime.getRuntime().exec(mysqldumpPath);
|
}
|
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream(), "utf8");
|
bufferedReader = new BufferedReader(inputStreamReader);
|
String line;
|
while ((line = bufferedReader.readLine()) != null) {
|
printWriter.println(line);
|
}
|
// 此次会执行过长时间,直到备份完成
|
printWriter.flush();
|
printWriter.close();
|
//0 表示线程正常终止。
|
if (process.waitFor() == 0) {
|
// 线程正常执行
|
log.info("【备份数据库】SUCCESS,SQL文件:{}", pathFileName);
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
log.info("【备份数据库】FAILURE");
|
} finally {
|
try {
|
if (bufferedReader != null) {
|
bufferedReader.close();
|
}
|
if (printWriter != null) {
|
printWriter.close();
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
log.info("【备份数据库】--END");
|
}
|
|
|
/**
|
* 每天晚上23点0分10秒执行 【 0 0 4 1/1 * ? 】
|
* 测试 20 秒一次【 0/20 * * * * ? 】
|
*/
|
// @Scheduled(cron = "6 0 23 * * ?")
|
private void TimerDeleteFile(){
|
Date date = new Date();
|
SimpleDateFormat sdf = new SimpleDateFormat("d");
|
Integer currentDay = Integer.valueOf(sdf.format(date));
|
File file = new File(filePath);
|
File[] files = file.listFiles();
|
if (files != null) {
|
for(File f : files){
|
if(f.isFile()){//若是文件,直接打印
|
String[] splitFile = f.getName().split("_");
|
Integer fileDay = Integer.valueOf(splitFile[splitFile.length - 2]);
|
Integer i = currentDay - fileDay;
|
if (i.equals(destiny)){
|
f.delete();
|
log.info("备份sql文件过多进行删除!");
|
}
|
}
|
}
|
}
|
}
|
|
|
/**
|
* 定时任务,每个月1号的00:00:00给下一个月排班
|
* 给每个人都进行排班(默认早班)
|
*/
|
@Scheduled(cron = "0 0 0 1 * ?")
|
//@Scheduled(cron = "0/20 * * * * ?")
|
private void timerCreateSchedule(){
|
System.out.println("开始给每个人进行排班,默认早班======start");
|
// TODO 给每个人都进行排班(默认早班)
|
PerformanceShiftAddDto performanceShiftAddDto = new PerformanceShiftAddDto();
|
//班次--早(查询字典)
|
List<Enums> shiftType = enumService.selectEnumByCategory("班次类型");
|
List<String> collect = shiftType.stream().filter(enums -> enums.getLabel().equals("早")).map(enums -> enums.getValue()).collect(Collectors.toList());
|
performanceShiftAddDto.setShift(collect.get(0));
|
//人员--所有人
|
String userIds = userService.getDeviceManager().stream().map(user -> user.getId().toString()).distinct().collect(Collectors.joining(","));
|
performanceShiftAddDto.setUserId(userIds);
|
//周次--当月所有
|
// 获取当前日期
|
LocalDate today = LocalDate.now().plusMonths(1);
|
// 获取本月的第一天和最后一天
|
LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
|
LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
|
// 获取周字段信息(根据区域设置)
|
WeekFields weekFields = WeekFields.of(Locale.getDefault());
|
// 获取本月第一天的周一
|
LocalDate startOfWeek = firstDayOfMonth.with(TemporalAdjusters.previousOrSame(weekFields.getFirstDayOfWeek()));
|
// 遍历本月所有天数,找出每周的第一天和最后一天
|
LocalDate endOfWeek;
|
while (startOfWeek.isBefore(firstDayOfMonth.plusMonths(1))) {
|
endOfWeek = startOfWeek.plusDays(6);
|
LocalDateTime startDateTime = LocalDateTime.of(startOfWeek, LocalTime.MIDNIGHT);
|
LocalDateTime endDateTime = LocalDateTime.of(endOfWeek, LocalTime.MIDNIGHT);
|
System.out.println("Week starts on " + startDateTime + " and ends on " + endDateTime);
|
performanceShiftAddDto.setStartWeek(startDateTime);
|
performanceShiftAddDto.setEndWeek(endDateTime);
|
performanceShiftService.performanceShiftAdd(performanceShiftAddDto);
|
startOfWeek = startOfWeek.plusWeeks(1);
|
}
|
|
System.out.println("排班结束======end");
|
}
|
|
/**
|
* 判断文件是否存在,不存在创建
|
*/
|
private static void existsFile(File file) {
|
// 判断文件路径是否存在,不存在新建
|
if (!file.getParentFile().exists()) {
|
file.getParentFile().mkdirs();
|
}
|
if (!file.exists()) {
|
try {
|
file.createNewFile();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}
|