java备份还原表数据

背景

需求:这个功能还是费了我一段时间才完成,大体的需求是这样的。 首先是
分模块,每个模块有不同的几个表,备份的时候就按照模块来备份数据,相当于一次性备份多张表的数据了,模块 和 模块拥有的表都是能配置的(即增删改查),主要是选择模块来备份这个麻烦点

思路

  • 备份
    备份的话我想到的是可以用导出xml文件的形式,第二种的话只用用mysql原生的mysqldump命令就好。
    最后用的mysqldump命令,这个容易实现一些。
  • 还原
    还原我查了下有 source 命令还原的,还有使用 mysqldump -h 主机IP -uroot -p db < /root/db.sql 命令进行还原的
    我使用的是后面一种。

命令使用方法

mysqldump命令

1.备份数据库

  • 备份所有数据库
mysqldump -h 主机IP -uroot -p --all-database > /usr/dball.sql
  • 备份多个数据库
mysqldump -h 主机IP -uroot -p db1 db2 db3 >/usr/db123.sql
  • 备份单个数据库
mysqldump -h 主机IP -uroot -p db >/usr/db.sql

2.备份数据库表

  • 备份多张表
mysqldump -h 主机IP -uroot -p db table1  table2 >/data/db_table12.sql
  • 备份单张表
mysqldump -h 主机IP -uroot -p db table   >/data/db_table.sql
  • 备份表时用 where 筛选
mysqldump -h 主机IP -uroot -p db table  --where " 查询条件" >/data/db_table.sql

还原

  • mysqldump命令还原
mysqldump -h 主机IP -uroot -p db < /root/db.sql
  • source命令
source /root/db.sql

实现

这里的话前后端是用的若依框架那一套,vue(elmentui)+springboot 实现。

后端

1.备份工具类

先写一个工具类方便调用,因为我前端的想法是把那些数据表的表名都传过来,所以我就留了个表名的参数。改的时候可以根据你传的数据改参数

public class MySQLDatabaseBackupUtils {/*** 备份数据库某些表**  host IP地址* userName 数据库的用户名*  password 数据库的密码*  savePath 备份文件的地址*  fileName 备份文件名称*  databaseName 需要备份的数据库的名称*  tableNames 表名如:test1 test2 test3*  mysqlBin mysql安装路径 如:E:\mysql-5.7.24-winx64\bin linux下:/usr/mysql/bin*  备份成功返回true, 否则返回false*/public static boolean backup(String tableNames,String fileName) {String host = "192.168.16.2";String userName = "root";String password = "root";//  String savePath = "D:\\文档\\backupFile";//服务器的保存地址String savePath = "/usr/backupFile";String databaseName = "audit";///usr/local/mysql/bin 安装路径String mysqlBin = "/usr/local/mysql/bin";File saveFile = new File(savePath);if (!saveFile.exists()) {// 如果目录不存在saveFile.mkdirs();// 创建文件夹}if (!savePath.endsWith(File.separator)) {savePath = savePath + File.separator;}//拼接命令行的命令// mysqldump --opt --host=localhost --databases backup --tables log_sys sys_user --user=root --password=root --result-file=E:\Sqldata\test.sql --default-character-set=utf8StringBuilder cmd = new StringBuilder();cmd.append(mysqlBin).append("/mysqldump").append(" --opt").append(" --host=").append(host).append(" --databases ").append(databaseName).append(" --tables ").append(tableNames).append(" --user=").append(userName).append(" --password=").append(password).append(" --result-file=").append(savePath + fileName).append(" --default-character-set=utf8 ");try {//调用外部执行exe文件的javaAPIProcess process = Runtime.getRuntime().exec(cmd.toString());if (process.waitFor() == 0) {// 0 表示线程正常终止return true;}} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}return false;}
}

2.备份seviceImpl层

我的前端传过来的是 用户选择的模块 以及 模块所属的表名 ,所以我只需要获取表名传入工具类,在用模块名拼接sql文件后缀就ok了。

    @Overridepublic boolean backupModule(List<SysDataBackupTable> sysDataBackupTable) {List<String> list = sysDataBackupTable.stream().map(SysDataBackupTable::getTableName).collect(Collectors.toList());String tableNames = String.join(" ", list);//获取模块名List<String> collect = sysDataBackupTable.stream().map(SysDataBackupTable::getTableModule).collect(Collectors.toList());String s = collect.get(0);String moduleName = s + ".sql";//调用备份工具类boolean backup = MySQLDatabaseBackupUtils.backup(tableNames, moduleName);return backup;}

还原

1.还原工具类

还原和备份差不多,不过要注意的是 要在linux 上面执行命令的话要加特殊的指令。
还有要注意的是 mysql -u 用户名 -p密码 。这里-p后面与密码直接不能有空格,否则会把你的密码当作数据库名

"/bin/bash","-c"
public class LinuxSqlImportUtils {public static boolean exportSql(String fileName){String user = "root";//mysql -u forceview -pforceview 不能有空格,所以这样写String password = "root";String host = "192.168.16.2";String exportDatabaseName = "audit";String exportPath = "/usr/backupFile";StringBuilder cmd = new StringBuilder();cmd.append("mysql").append(" -u ").append(user).append(" -p").append(password).append(" ").append(exportDatabaseName).append(" < ").append(exportPath).append("/").append(fileName);//执行命令String[] command = {"/bin/bash","-c",cmd.toString()};//使用拼接的方式来完成dos命令//windows 用cmd/k// String command = new String("cmd /k mysql"+" -h"+host+" -u"+user+" -p"+password+" "+exportDatabaseName+" <"+exportPath+"\\"+fileName);
//        System.out.println(cmd.toString());try {Process process = Runtime.getRuntime().exec(command);if (process.waitFor() == 0){return true;}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}return false;}}

前端

前端我是这样想的,使用一个选择框,选择你想导出的模块,这样选择后就会查出属于某个模块的表,再把表名后模块名传过去;

备份

<el-row ><el-form :inline="true" label-width="100px" ><el-form-item label="数据备份表"><el-selectv-model="queryParams.tableModule"@change="changeSelect()"placeholder="请选择模块"><el-optionv-for="item in selectChangeList":key="item.id":label="item.tableModule":value="item.tableModule"></el-option></el-select></el-form-item></el-form></el-row>


比如选择aaa模块进行备份,备份后就会生成一个sql文件在你所指定的路径中,我下面实在window测试的,linux也测试过了。


js代码

 //备份按钮handleBackupModule(){this.$modal.confirm('是否确认备份该模块的表数据?').then(()=>{backupModule(this.sysDataBackupList).then(response=>{if(response.code == 200){this.$message({message: "备份成功",type: "success"});this.getFileTable();}else{this.$message({message: "备份失败",type: "error"});this.getFileTable();}});}).catch(()=>{this.$message({message: "取消备份",type: "info"});this.getFileTable();});},

还原 及 下载到本地

还原的话就在 查出来的 sql文件 表格后面加一个还原按钮就好,这两个就不详细描述了。

下载到本地的话用的若依自带的download方法。

 //还原handleRetoreFile(row){this.$modal.confirm('是否确认还原该sql文件?').then(()=>{restoreFile(row.fileName).then(res=>{if(res.code == 200){this.$message({message: "还原成功",type: "success"});this.getFileTable();}else{this.$message({message: "还原失败",type: "error"});this.getFileTable();}});}).catch(()=>{this.$message({message: "取消还原",type: "info"});}) },
 //下载handleDownloadFile(row){const fileName = row.fileNamethis.download("/dataBackup/downloadFile?fileName=" + fileName,{...fileName,},fileName);},

下载业务层

@Overridepublic boolean downloadFile(String fileName, HttpServletRequest request, HttpServletResponse response) {String filePath = path + "/" +fileName;File file = new File(filePath);response.setCharacterEncoding("UTF-8");String realFilename = file.getName();response.setHeader("content-type", "application/octet-stream;charset=UTF-8");response.setContentType("application/octet-stream;charset=UTF-8");if (file.exists()){try {response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(realFilename.trim(), "UTF-8"));BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());byte[] bytes = new byte[1024];int len;while ((len = inputStream.read(bytes,0,bytes.length)) != -1){outputStream.write(bytes,0,len);}outputStream.close();inputStream.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}return true;}

上传

上传的话用的elmentui 上的上传组件,贴一下前后端

html

 <el-dialogtitle="导入":visible.sync="FileTable.upload.open"width="400px"append-to-body><el-uploadref="upload":limit="1"accept=".sql":headers="FileTable.upload.headers":action="FileTable.upload.url":disabled="FileTable.upload.isUploading":on-progress="handleFileUploadProgress":on-success="handleFileSuccess":auto-upload="false"drag><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip text-center" slot="tip"><div class="el-upload__tip" slot="tip"><!-- <el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据 --></div><span>仅允许导入sql文件。</span><!-- <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link> --></div></el-upload><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitFile">确 定</el-button><el-button @click="FileTable.upload.open = false">取 消</el-button></div></el-dialog>

data

FileTable: {// 遮罩层loading: true,// 选中数组ids: [],// 非单个禁用single: true,// 非多个禁用multiple: true,// 显示搜索条件showSearch: true,// 总条数total: 0,// 数据备份表模块表格数据FileList: [],// 弹出层标题title: "",// 是否显示弹出层open: false,// 查询参数queryParams: {pageNum: 1,pageSize: 10,fileName: ""},// 表单参数form: {},// 表单校验rules: {},upload: {// 是否显示弹出层(用户导入)open: false,// 弹出层标题(用户导入)title: "",// 是否禁用上传isUploading: false,// 是否更新已经存在的用户数据// updateSupport: 0,// 设置上传的请求头部headers: { Authorization: "Bearer " + getToken() },// 上传的地址url: "https://192.168.16.22/dataBackup/importFile",},

js

 //导入importFile(){this.FileTable.upload.open = true;},// 文件上传中处理handleFileUploadProgress(event, file, fileList) {this.FileTable.upload.isUploading = true;},// 文件上传成功处理handleFileSuccess(response, file, fileList) {this.FileTable.upload.open = false;this.FileTable.upload.isUploading = false;this.$refs.upload.clearFiles();this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +response.msg +"</div>","导入结果",{ dangerouslyUseHTMLString: true });this.getFileTable();},// 提交上传文件submitFile() {this.$refs.upload.submit();},

上传的业务层

  @Overridepublic boolean importFile(MultipartFile file) {try {InputStream inputStream = file.getInputStream();String name = file.getOriginalFilename();String newPath = path + "/" + name;File uploadFile = new File(newPath);byte[] buffer = new byte[2048];int len = 0;FileOutputStream outputStream = new FileOutputStream(uploadFile);while ((len = inputStream.read(buffer)) != -1){outputStream.write(buffer,0,len);}outputStream.close();inputStream.close();} catch (IOException e) {e.printStackTrace();}return true;}

java 实现对数据表的备份与还原(备份与还原 到服务器中)相关推荐

  1. java jsf table_JSF数据表(h:dataTable)排序数据

    JSF中有一个叫作DataTable的控件,可用来渲染和格式化html表格.使用DataTable,我们可以迭代收集或数组数组来显示数据.下面我们来学习如何向DataTable排序数据. 要使用Dat ...

  2. Java案例:数据表转换成XML文档

    将数据表查询内容转换成XML文件,便于在网络上进行传输,具有一定的实用价值.   1.数据表(student) 2.数据库连接管理类 /*** 功能:获得数据库连接* 作者:华卫* 日期:2010年4 ...

  3. datatable java排序,JSF数据表(h:dataTable)DataModel排序数据

    JSF中有一个叫作DataTable的控件,可用来渲染和格式化html表格.使用DataTable,我们可以迭代收集或数组数组来显示数据.下面我们来学习如何向DataTable使用DataModel排 ...

  4. java 实现内存数据表_数据结构 Java中的内存

    根据线性表的实际存储方式,分为两种实现模型: 顺序表 ,将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示. 链表 ,将元素存放在通过链接构造起来的一系列存储块中. 一.顺 ...

  5. java引用其他类的数据头文件_Java 实现数据表与简单Java类映射转换

    我们在程序开发过程中往往会使用简单Java类进行数据表结构的描述,本文主要介绍如何简单Java类与数据表之间的转换. 首先,先简单介绍一下数据表与简单Java类的相关概念对比: 表的定义 → 实体表设 ...

  6. 数据表-java类的映射

    1.一个数据表对应一个java类2.数据表的字段对应java类的属性3.一对多的数据表关系一方用一个java对象表示多方用一个java对象数组表示4.多对多的数据表关系:采用中间表,将多对多转为多对一 ...

  7. 电脑中毒软件都变成java图标_当前数据表有10条记录,若用函数EOF()测试结果为.T.,此时函数RECNO()值是________。 (2.0分)_学小易找答案...

    [单选题]洁净室的内表面应 [单选题]当前数据表有10条记录,若用函数EOF()测试结果为.T.,此时函数RECNO()值是________. (2.0分) [单选题]LD50与毒性评价的关系是 [单 ...

  8. sql数据表改为自动递增显示与其他表关联_MySQL萌新第一季 第四话-数据表的基本操作...

    本话旨在完成以下内容: 在数据库中,数据表是数据库中最重要和基本的操作对象,是数据存储的基本单位.换句话说我们操作数据库其实重要的就是操作数据表.本章将详细介绍数据表的基本操作,主要内容包括:创建数据 ...

  9. MySQL第二讲 - 数据表简单操作 与 “增删查改的开头部分- 增”- 细节狂魔

    文章目录 前文知识点回顾   SQL语句 >>操作指令 (不区分大小写) 1.显示数据库:show databases; 2.创建数据库:create database 数据库名; [如果 ...

最新文章

  1. c语言结构体中的ps,练习结构体的时候出错,(ps有两个函数还没写)
  2. 【 FPGA 】状态机,FPGA的灵魂
  3. vb和python-vb与python
  4. golang-flag的问题
  5. 《大型网站技术架构》读书笔记三:大型网站核心架构要素
  6. oracle连接的内存,简单查看oracle的连接情况和内存使用情况 -电脑资料
  7. 一个小例子体会Java反射的动态性
  8. python基础之序列类型的方法——列表元组
  9. 【华为云 ModelArts-Lab AI实战营】第三期:图像分类 (III) 模型参数网络调优
  10. PPTP-***第三章——用户流量与并发数限制
  11. Singularity将本地SIF文件,转成sandbox
  12. 堆插入和删除的简单实现
  13. android跑马灯源码,Android跑马灯的简单实现方式
  14. 循环系统疾病病人的护理题库【2】
  15. C语言实验报告(通用)
  16. Photoshop插件-删除所有亮度通道蒙板-脚本开发-PS插件
  17. 台式计算机调整显示亮度,台式电脑显示器屏幕亮度怎么调节?
  18. Python数据分析基础(2)
  19. Anbox源码分析(三)——Anbox渲染原理(源码分析)
  20. Python中对于Json空对象的处理

热门文章

  1. C++实现愤怒小鸟小游戏
  2. phpStudy无法打开http://localhost/
  3. 推荐低保真原型设计软件 Balsamiq Mockup
  4. 使用form表单文件上传(enctype)
  5. Maven 编译时缺少依赖,java: 程序包org.apache.http不存在
  6. 关于单片机的C语言编程基础知识(初学注意)
  7. BitBlt C++中BitBlt如何使用详解
  8. C#如何获取本机IP地址,两种方法
  9. Oracle 12c 的安装步骤教程
  10. 计算机组成原理——奇偶校验,海明校验,循环冗余校验