springboot执行bat备份MySQL文件

原创
2023/12/20 16:42
阅读数 132

需求:1、bat执行备份MySQL数据;

           2、windows制定执行计划;

           3、springboot执行bat

实现:

        1、bat执行备份MySQL数据  

@echo off
echo =============================
echo ### mysql database backup bat
echo =============================

echo =========当前日期时间==========
set nowdate=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%
echo %nowdate%
echo =============================

echo =========IP地址和端口==========
set ipconfig=ip地址
echo %ipconfig%
echo =============================

echo ======进入到mysql安装目录======
D:
cd D:\program\mysql\mysql-5.7.21-winx64\bin
echo =============================

echo ====备份mysql文件到指定文件夹====
echo mysql文件备份中...
echo =============================
mysqldump -h%ipconfig% -uroot -phake2019 --databases ms_test > "D:\MySQLBack_File\copy_%ipconfig%_%nowdate%.sql"
echo MySQL 备份成功
echo =============================

echo 备份的sql文件
forfiles /p "D:\MySQLBack_File" /s /m *.sql
echo =============================

rem 获取"D:\MySQLBack_File"目录下的sql文件,并且删除7天前的文件
echo *********************
echo * 按时间删除7天前的sql文件 *
echo *********************
echo 删除操作前存在的sql文件
forfiles /p "D:\MySQLBack_File" /s /m *.sql
echo =============================

rem 删除sql文件操作
forfiles /p "D:\MySQLBack_File" /s /m *.sql /d -7 /c "cmd /c del /q /f @path"

echo 删除操作后存在的sql文件
forfiles /p "D:\MySQLBack_File" /s /m *.sql
echo =============================

rem 不关闭窗口操作
rem pause>nul 表示命令窗口不会出现“请按任意键继续”
rem pause>nul

rem 关闭窗口
@echo 数据库备份操作完成,5秒后关闭程序...
ping /n 10 127.1 >nul
exit

        2、制定windows定时任务

             网上找

        3、springboot集成bat执行

         3.1 

package com.hake.utils;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.File;
import java.time.LocalDateTime;

/**
 * 执行bat 文件的
 * @author liuyue
 * @date 2023/12/12 9:10

 */

@Component
@Slf4j
public class ExecuteBatFileUtils {

    private static ExecuteBatFileUtils executeBatFileUtils;

    @Autowired
    private YmConfig ymConfig;

    @PostConstruct
    public void init() {
        executeBatFileUtils = this;
        executeBatFileUtils.ymConfig = this.ymConfig;
    }

    public static int count = 26000;
    public static int exitCode = 3;

    public static int backDatabase(){
        try {
            long beginTime = System.currentTimeMillis();
            log.info("开始时间:{},{}", LocalDateTime.now(), beginTime);
            //创建processBuilder对象
            ProcessBuilder processBuilder = new ProcessBuilder(executeBatFileUtils.ymConfig.getBateFile());
            //设置工作目录
            processBuilder.directory(new File(executeBatFileUtils.ymConfig.getBateWorkFile()));
            //执行bat文件
            Process process = processBuilder.start();

            exitCode = process.waitFor();
            long endTime = System.currentTimeMillis();

            log.info("结束时间:{} ,{} ",LocalDateTime.now(), endTime);
            log.info("用时:{}", endTime-beginTime);
            if (exitCode==1 || exitCode ==0){
                log.info("备份数据库 Exit Code:{}",exitCode);
                Thread.sleep(1000);
                exitCode=3;
            }else {
                log.info("备份失败 Exit Code:{}",exitCode);
            }
        }catch (Exception ex){
            log.error("备份数据库错误:{}",ex.getMessage());
        }
        return 200;
    }
}

    3.2 service方法

         

    @Override
    public int backDatabase(){
        try {
            int i = ExecuteBatFileUtils.backDatabase();
            return i;
        }catch (Exception ex){
            log.error("执行bat失败,备份数据库失败");
            return 201;
        }
    }

3.3 controller层

   public int rsf = 0;

   /**
     * 优化异步通知
     * @author liuyue
     * @date 2023/12/19 9:30
     * @return BaseResponse
     */

    @UnRequiredPermission(value = "true")
    @GetMapping("backDatabase")
    public synchronized BaseResponse backDatabasePlus(){
        try {
            Runnable runnable = () -> {
                log.info("数据备份完成,执行回调");
                rs = 0;
                log.info("执行备份,结束执行时间:{}", LocalDateTime.now());
            };
            rs = 100;
            log.info("执行备份,执行时间:{}", LocalDateTime.now());
            new Thread(()->{
                for (int i=ExecuteBatFileUtils.count;i>0;i=i-100){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    //log.info("i的值:{},rs的值:{}",i,rs);
                    if (rs==0){
                        break;
                    }
                    rs = i;

                }
            }).start();
            performAsynchronousAction(runnable);
            return successToJson(200);
        }catch (Exception e){
            log.error("备份失败,失败原因:{}", e.getMessage());
            return fail("备份失败");
        }
    }
    private void performAsynchronousAction(Runnable runnable){
        new Thread(() -> {
            iHkBackDatabase.backDatabase();
            // 创建一个新的线程执行回调
            runnable.run();
        }).start();
    }
    /**
     * 备份数据库进度
     * @author liuyue
     * @date 2023/12/12 12:39
     * @return BaseResponse
     */
    @UnRequiredPermission(value = "true")
    @GetMapping("delayTime")
    public BaseResponse delayTime(){
        return successToJson(rs);
    }

 

    此处的重点,在查看备份的进度,我实现的思路是启动一个线程备份数据库,第二个线程定义一个进度每次减100,备份完成后有个回调函数,返回一个值,修改rs的值。第二个现场判断rs的值等于0之后,直接显示备份完成。大家有什么好的思路,欢迎大家指教。

     每天进步一点点!  ControllerExecuteBatFileUtils ExecuteBatFileUtils

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部