Springboot使用ProcessBuilder创建系统进程执行shell命令备份数据库

文章目录

    • 概要
    • 1、查看mysql版本
    • 2、相关依赖
    • 3、具体代码
    • 技术细节

概要

Springboot执行shell命令备份数据库。

1、查看mysql版本

mysql --version

在这里插入图片描述

2、相关依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.20</version>
</dependency>

3、具体代码

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDate;
import org.springframework.core.io.ResourceLoader;@Component
@Slf4j
public class BackupJob {//数据库连接地址@Value("${spring.datasource.url}")private String dbUrl;//数据库名@Value("${spring.datasource.name}")private String dbName;//用户名@Value("${spring.datasource.username}")private String dbUserName;//密码@Value("${spring.datasource.password}")private String dbPassWord;//存放路径@Value("${backup.path}")private String filePath;// 在你的类中注入ResourceLoader,用来获取备份的sql文件@Autowiredprivate ResourceLoader resourceLoader;/*** 数据库版本是否为 8.0 + (false=否  true=是), mysql8+ 需要参数  --column-statistics=0  , mysql8- 不需要* 新版的mysqldump默认启用了一个新标志,通过--column-statistics=0来禁用*/boolean isDbVersion8 = true;@SneakyThrowspublic void backup() {log.info("【备份数据库】--START");String dbUrl2 = dbUrl.replace("jdbc:mysql://", "");// 获取数据库地址String[] serverPath = dbUrl2.substring(0, dbUrl2.indexOf("/")).split(":");String ip = serverPath[0];String port = serverPath[1];// 数据库账号String username = dbUserName;// 数据库密码String password = dbPassWord;String dbParam = "";// 备份文件目录+名称  备份文件存放目录+名称(名称 = 数据库名+时间字符串.sql)String timeStr = LocalDate.now().toString();String pathFileName = filePath + dbName + "_" + timeStr + ".sql";String newCmd = "mysqldump -h{SERVER-PATH} -P{SERVER-PORT} -u{USERNAME} -p{PASSWORD} {DBNAME} {DB-PARAM} > {FILEPATH}";if(isDbVersion8){dbParam = "--column-statistics=0";}// 执行命令newCmd =  newCmd.replace("{USERNAME}", username).replace("{PASSWORD}", password).replace("{SERVER-PATH}", ip).replace("{DBNAME}", dbName).replace("{SERVER-PORT}", port).replace("{FILEPATH}", pathFileName).replace("{DB-PARAM}", dbParam);//这里打印出来的命令是可以直接在 终端执行的。System.out.println(newCmd);System.out.println(pathFileName);// 创建进程构建器ProcessBuilder processBuilder = new ProcessBuilder();// 设置命令和参数processBuilder.command(getOsShell(), "-c" , newCmd);
//        processBuilder.command(getOsShell(), "/c" , newCmd);// 启动进程Process process = processBuilder.start();// 获取命令执行的输出流InputStream inputStream = process.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));// 读取输出String line;while ((line = reader.readLine()) != null) {log.info(line);}// 等待命令执行完成int exitCode = process.waitFor();System.out.println("命令执行完成,退出码:" + exitCode);if (exitCode == 0) {log.info("数据库备份成功!");} else {log.info("数据库备份失败!");}//TODO 获取文件备份的文件、上传到云服务。
//        Resource resource = resourceLoader.getResource("file:" + pathFileName);
//        InputStream inputStream = resource.getInputStream();
//        byte[] bytes = IoUtil.readBytes(resource.getInputStream());//TODO 同步备份记录到数据库//TODO 删除指定文件
//        FileUtil.del(pathFileName);}public String getOsShell() {String osName = System.getProperty("os.name");// TODO Windows未测试if (osName.toLowerCase().contains("windows")) {return "cmd.exe";} else if (osName.toLowerCase().contains("mac")) {return "/bin/bash";} else if (osName.toLowerCase().contains("linux")) {return "/bin/bash";}return "";}}

技术细节

主要就是使用ProcessBuilder创建系统进程,执行终端命令。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/97278.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【力扣-每日一题】901. 股票价格跨度

暴力解法&#xff1a; class StockSpanner { private:vector<int> pri; public:StockSpanner() {}int next(int price) {pri.emplace_back(price);int count0;for(int ipri.size()-1;i>0;i--){if(pri[i]<price)count;else break;}return count;} };/*** Your Stoc…

AI 大框架基于python来实现基带处理之TensorFlow(信道估计和预测模型,信号解调和解码模型)

AI 大框架基于python来实现基带处理之TensorFlow(信道估计和预测模型,信号解调和解码模型) 基带处理&#xff08;Baseband Processing&#xff09;是一种信号处理技术&#xff0c;用于在通信系统中处理和调制基带信号。基带信号是指未经过调制的信号&#xff0c;通常包含原始数…

如何使用API进行大规模数据收集和分析

在当今信息爆炸的时代&#xff0c;如何高效地进行大规模数据收集和分析是一项重要的能力。API&#xff08;Application Programming Interface&#xff09;作为一种常见的数据交互协议&#xff0c;提供了访问和操作数据的接口&#xff0c;为我们提供了便利。本文将介绍如何使用…

HDLbits: ece241 2014 q7b

题目要求用10进制的BCD计数器来构造1000计数&#xff0c;其实也是将1000hz的时钟信号改造成1hz&#xff0c;我们首先计算出10的三次方等于1000&#xff0c;需要三个10进制的计数器&#xff0c;去计999的中高低位。 最低位的计数器一直在对时钟信号计数&#xff0c;因此enable1…

Perforce发布《2023游戏开发与设计现状报告》,为游戏开发行业提供参考

近期&#xff0c;Perforce发布了《2023游戏开发与设计现状报告》。此报告调查了来自全球各地的游戏开发专业人士&#xff0c;了解他们面临的主要开发挑战、使用的工具和流程&#xff0c;以及目前最让他们对这个行业感到兴奋的方面。 龙智作为Perforce授权合作伙伴&#xff0c;…

第85步 时间序列建模实战:CNN回归建模

基于WIN10的64位系统演示 一、写在前面 这一期&#xff0c;我们介绍CNN回归。 同样&#xff0c;这里使用这个数据&#xff1a; 《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrome i…

什么是生成式人工智能?人工智能创造

原文地址&#xff1a;什么是生成式人工智能&#xff1f;人工智能创造 生成式人工智能模型可以进行对话、回答问题、编写故事、生成源代码以及创建几乎任何描述的图像和视频。以下是生成式人工智能的工作原理、使用方式以及其局限性比您想象的要大的原因。 生成式人工智能是一种…

【JavaEE重点知识归纳】第6节:数组

目录 一&#xff1a;数组的基本概念 1.什么是数组 2.数组的创建和初始化 3.数组的使用 ​编辑二&#xff1a;数组是引用类型 1.了解JVM的内存分布 2.基本类型变量和引用类型变量的区别 3.认识null 三&#xff1a;数组的应用场景 1.保存数据 2.作为函数的参数 3.作为…

BUUCTF Basic 解题记录--BUU XXE COURSE

1、XXE漏洞 初步学习&#xff0c;可参考链接&#xff1a; 一篇文章带你深入理解漏洞之 XXE 漏洞 - 先知社区 2、了解了XXE漏洞&#xff0c;用burpsuite获取到的url转发给repeater&#xff0c;修改XML的信息&#xff0c;引入外部实体漏洞&#xff0c;修改发送内容&#xff0c;…

ubuntu系统开机黑屏(只显示logo、左上角光标闪烁)问题

问题背景 在使用pycharm的时候&#xff0c;我使用了pycharm的快捷键ctrlaltF7&#xff0c;结果进入了ubuntu的ttf界面&#xff0c;由于之前不知道这个东西&#xff0c;百度一顿乱搜&#xff0c;以为显卡驱动出问题了&#xff0c;就把驱动删了&#xff0c;其实我完全可以ctrlal…

kotlin:list的for循环

代码&#xff1a; var list { "a", "b", "c" } for (i in list.indices) {print("app"i""list[i]) }

Library <iconv2.4.0> not found 解决方法

1、升级到Xcode15之后&#xff0c;跑到C的库出现了这个问题。 2、于是去Xcode里面搜了一下&#xff0c;这个库已经搜不到了&#xff0c;但是项目里还是配置的&#xff0c;于是接下意识把它删掉了&#xff0c;就不报错了&#xff0c;顺手还把类似的这个库给加进去了 3、而且跑起…

[JAVAee]SpringBoot-AOP

目录 Spring AOP ​编辑AOP适用场景 AOP的组成 连接点(Join Point) 切点(Pointcut) 通知(Advice) Spring AOP的实现 添加依赖 定义切面与切点 切点表达式的说明 定义相关的通知 Spring AOP AOP(Aspect Oriented Programming)是面向切面编程,是一种设计思想.对某一类…

termius mac版无需登录注册直接永久使用

1. 下载地址&#xff1a;termius下载 2. 解压安装 3. 当出现 “termius”已损坏,无法打开 则输入以下命令即可&#xff1a;sudo xattr -r -d com.apple.quarantine /Applications/Termius.app 最后去 系统设置-> 隐私与安全性-> 仍要打开 4. 删除app-update.yml文件&…

竞赛选题 深度学习 python opencv 动物识别与检测

文章目录 0 前言1 深度学习实现动物识别与检测2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存…

Android Camera FW 里的requestId和frameId

安卓相机frameworks里面经常出现requestId和frameId&#xff0c;最近简单看了一下代码&#xff0c;发现相关流程还是很复杂的&#xff0c;总结来看requestId 就是上层&#xff08;java&#xff09;发送的repeating(capture)请求的id&#xff0c;是从0开始递增的。 这是CameraD…

jira 浏览器插件在问题列表页快速编辑问题标题

jira-issueTable-quicker 这是一个可以帮助我们在问题表格页快速编辑问题的浏览器插件 github 地址 功能介绍 jira 不可否认是一个可以帮助有效提高工作效率的工具&#xff0c;但是我们在使用 jira 时使用问题表格可以让我们看到跟多的内容而不用关注细节&#xff0c;但是目…

简单两步实现离线部署ChatGPT,ChatGPT平替版,无需GPU离线搭建ChatGPT

文末附主程序安装包和大模型参数文件~ 演示效果如下图所示&#xff1a; 一、使用方法 软件主要分为两个部分&#xff1a;GPT4ALL软件主体&#xff08;主程序&#xff09;模型参数&#xff08;离线模型&#xff09;&#xff0c;如果使用API Key的话则不需要下载模型参数。 可以…

GPIO定义

//LED端口定义 #define LED0 PBout(8) // DS0 work #define LED1 PBout(9) // DS1 txrx#define POWA_ON GPIO_SetBits(GPIOA,GPIO_Pin_5) //继电器1 #define POWA_OFF GPIO_ResetBits(GPIOA,GPIO_Pin_5)#define POWB_ON GPIO_SetBits…

2023牛客OI赛前集训营-提高组(第一场) 情景剧

题目大意 有一个长度为 n n n的序列 h i h_i hi​&#xff0c;一段区间 [ l , r ] [l,r] [l,r]的有趣程度为这段区间上 h i h_i hi​的最大值 \times 最小值 \times 区间长度。求所有区间中有趣程度的最大值&#xff0c;输出这个最大值。 保证答案在 unsigned long long \t…