数据备份文件生成--根据表名生成对应的sql语句文件
最近客户有个需求,希望在后台增加手动备份功能,将数据导出下载保存。
当然,此方法不适用于海量数据的备份,这只适用于少量数据的sql备份。
这是我生成的sql文件,以及sql文件里的insert语句,已亲测,可以直接执行:


项目是SSM框架,接下来就展示我的实现代码:
首先是接受字段的实体类:
@Data
public class ColumnsDto {/*** 表结构的主要字段**/private String column_name;//该字段则是表字段的数据类型 暂时不需要private String data_type;}
然后是用的到两个主要的sql:
1.此sql用于查询表的有效字段信息(table_schema:当前的数据库名)
<select id="queryColumnsByTableName" resultType="com.hle.monitor.entity.vo.ColumnsDto">SELECTcolumn_name,data_typeFROMinformation_schema.COLUMNSWHEREtable_name = #{tableName}AND table_schema = 'supervision_data'ORDER BY ordinal_position</select>
2.再用sql查询表的所有数据:(注意:此处表名需要要用$而不是#号)
<select id="findBackupAll" resultType="java.util.Map">select * from ${tableName}</select>
此处我省略了相应的service和mapper文件内容,直接展示最重要的controller代码:
import com.hle.monitor.entity.Results;
import com.hle.monitor.entity.vo.ColumnsDto;
import com.hle.monitor.service.UserService;
import com.hle.monitor.util.DateUtils;
import com.hle.monitor.util.MinIoUtil;
import com.hle.monitor.util.ParameterUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;/*** @author*/
@CrossOrigin(origins = "*")
@RestController()
@RequestMapping("/backup")
@Api(tags = "备份相关接口类")
@Scope("prototype")
public class BackupController {@Autowiredprivate UserService userService;@ResourceMinIoUtil minIoUtil;//本地文件夹路径private static String backupFilePath = "./sql/";@ApiOperation(value = "根据表名备份信息")@GetMapping("/{tableName}")public Results backupTable(@PathVariable("tableName") String tableName) {//表有效字段信息List<ColumnsDto> columnsDtoList = userService.queryColumnsByTableName(tableName);if(columnsDtoList.isEmpty()) return new Results(500, "该表无有效字段信息!");//文件名--先在本地创建写入后再进行删除String fileName = System.currentTimeMillis() + "-" + tableName + ".sql";try {//获取所有备份数据List<Map<String, Object>> records = userService.findBackupAll(tableName);String path = backupFilePath + fileName;//不存在文件夹则创建File directory = new File(backupFilePath);directory.mkdirs();BufferedWriter writer = new BufferedWriter(new FileWriter(path));for (Map record : records) {String insertStatement = generateInsertStatement(tableName, record, columnsDtoList) + ";";writer.write(insertStatement);writer.newLine();}writer.close();File file = new File(path);InputStream inputStream = new FileInputStream(file);MultipartFile multipartFile = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);minIoUtil.upload(multipartFile, ParameterUtil.bucketNameParam, fileName);//上传后 删除本地文件file.delete();System.out.println("Backup created successfully!");} catch (IOException e) {e.printStackTrace();return new Results(500, "操作失败!");}return new Results(200, "操作成功!", fileName);}//此方法需要以数据库取出来的字段信息为准--转换成sql的方法private String generateInsertStatement(String tableName, Map<String, Object> record, List<ColumnsDto> columnsDtoList) {StringBuilder builder = new StringBuilder();builder.append("INSERT INTO ").append(tableName).append(" (");//拼接列名columnsDtoList.forEach(columns -> {builder.append(columns.getColumn_name()).append(", ");});builder.setLength(builder.length() - 2);builder.append(") VALUES (");//拼接值columnsDtoList.forEach(columns -> {Object value = record.get(columns.getColumn_name());if(value instanceof Date){Date date = (Date) value;builder.append("'").append(DateUtils.parseDateToStr(date)).append("', ");}else if(value instanceof String){builder.append("'").append(value).append("', ");}else{builder.append(value).append(", ");}});builder.setLength(builder.length() - 2);builder.append(")");return builder.toString();}//此方法用于直接取Object的字段信息做sql拼接--转换成sql的方法--已验证过private String generateInsertStatement(String tableName, Object record) {StringBuilder builder = new StringBuilder();builder.append("INSERT INTO ").append(tableName).append(" (");Arrays.stream(record.getClass().getDeclaredFields()).map(Field::getName).forEach(fieldName -> builder.append(convertCamelCaseToSnakeCase(fieldName)).append(", "));builder.setLength(builder.length() - 2);builder.append(") VALUES (");Arrays.stream(record.getClass().getDeclaredFields()).map(field -> {field.setAccessible(true);try {return field.get(record);} catch (IllegalAccessException e) {e.printStackTrace();return null;}}).forEach(value -> {if(value instanceof Date){//时间格式 转换为-YYYY_MM_DD_HH_MM_SSDate date = (Date) value;builder.append("'").append(DateUtils.parseDateToStr(date)).append("', ");}else if(value instanceof String){builder.append("'").append(value).append("', ");}else{//int/double类型 不需要单引号builder.append(value).append(", ");}});builder.setLength(builder.length() - 2);builder.append(")");return builder.toString();}//驼峰命令转换 userName-转换为-user_namepublic static String convertCamelCaseToSnakeCase(String input) {return input.replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase();}}
在controller中提供了两种方法,可以参考一下~,然后直接调用接口就行:

因为项目需要,我是写入文件后再上传至minio文件服务器,所以我要查看还需要去minio服务器查看下载,或者调用现有的下载接口下载~

这样就完成了根据sql文件数据备份~
相关文章:
数据备份文件生成--根据表名生成对应的sql语句文件
最近客户有个需求,希望在后台增加手动备份功能,将数据导出下载保存。 当然,此方法不适用于海量数据的备份,这只适用于少量数据的sql备份。 这是我生成的sql文件,以及sql文件里的insert语句,已亲测&#x…...
进程同步与互斥
目录 进程同步与互斥(1) 第一节、进程间相互作用 一、相关进程和无关进程 二、与时间有关的错误 第二节、进程同步与互斥 一、进程的同步 二、进程的互斥 三、临界区 进程同步与互斥(2) 三、信号量与P、V操作的物理含义…...
mysql workbench常用操作
1、No database selected Select the default DB to be used by double-clicking its name in the SCHEMAS list in the sidebar 方法一:双击你要使用的库 方法二:USE 数据库名 2、复制表名,字段名 3、保存链接...
【操作】国标GB28181视频监控EasyGBS平台更新设备信息时间间隔
国标GB28181协议视频平台EasyGBS是基于GB28181协议的视频监控云服务平台,可支持多路设备同时接入,并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。平台可提供视频监控直播、云端录像、云存储、检索回放、智能告警、语音对讲、平台…...
TensorFlow入门(八、TensorBoard可视化工具的应用)
TensorBoard常用函数和类http://t.csdn.cn/Hqi9c TensorBoard可视化的过程: ①确定一个整体的图表,明确从这个图表中获取哪些数据的信息 ②确定在程序的哪些节点、以什么样的方式进行汇总数据的运算,以记录信息,比如在反向传播定义以后,使用tf.summary.scalar记录损失值的变…...
升级targetSdkVersion至33(以及迁移至Androidx)
1.设置 android.useAndroidXtrue 和 android.enableJetifiertrue 2.一键迁移至androidx:Refactor -> Migrate to Androidx 3.手动修改未能自动迁移到androidx的部分: android.support.v4.view.ViewPager.PageTransformer -> androidx.viewpager.wi…...
python3.11版本pip install ddddocr调用时报错got an unexpected keyword argument ‘det‘ 解决
一、如图出现如下问题 ddddocr.__init__() got an unexpected keyword argument det出现问题原因:python3.11默认安装版本就旧版的ddddocr1.0的,所以导致如下报错 二、解决方案一(推荐) python3.11的环境直接安装这个即可&…...
代理IP与Socks5代理:跨界电商之安全防护与智能数据引擎
第一部分:跨界电商的兴起与网络安全挑战 1.1 跨界电商的崭露头角 跨界电商已经成为全球贸易的新引擎,企业纷纷踏上了拓展国际市场的征程。 1.2 网络安全的不容忽视 跨界电商的增长也伴随着网络安全威胁的增加。黑客攻击、数据泄露和欺诈行为等风险呈…...
如何评估一个HR是否专业?看这些标准
HR在遇到优秀的人才时,以往的招聘中,我们总以惯性思维寻找吸引人才的突破口,诸如体现薪酬优厚、突出平台优势甚至提高面试话术等,却忽略了面试官本人的人格魅力,本身就是公司招聘的形象代言,因为优秀的面试…...
WordPress主题开发( 八)之—— 模板循环详细用法
WordPress 主题开发教程手册 — 模板循环 WordPress 主题开发中,模板循环是一个非常关键的概念,它负责默认机制来输出文章内容。模板循环会遍历当前页面获取的所有文章,然后使用主题中的模板标签将它们格式化并输出。 模板循环的应用 Word…...
QT : 完成绘制时钟
1.头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPainter> #include <QTimer> #include <QTime> #include <QPaintEvent> #include <QDebug> #include <QBrush>QT_BEGIN_NAMESPACE namespace Ui { class…...
香港云服务器和日本云服务器哪个好?(详细对比)
购置海外服务器时,您是在乎网络速度?价格?稳定性?当这几个因素同时存在,我们该如何选择?本篇针对海外热门的两个地区,中国香港和日本,这两种云服务器谁优谁劣?各有什么亮点?逐一进行对比分析。 一、速度上来看 中国香…...
Cross Attention和 Self- Attention 的区别?
Cross Attention和Self-Attention都是深度学习中常用的注意力机制,用于处理序列数据,其中Self-Attention用于计算输入序列中每个元素之间的关系,Cross Attention则是计算两个不同序列中的元素之间的关系。它们的主要区别在于计算注意力分数时…...
《从零开始的Java世界》02面向对象(基础)
《从零开始的Java世界》系列主要讲解Javase部分,从最简单的程序设计到面向对象编程,再到异常处理、常用API的使用,最后到注解、反射,涵盖Java基础所需的所有知识点。学习者应该从学会如何使用,到知道其实现原理全方位式…...
pve关闭windows虚拟机慢
背景: 在web界面关闭windows虚拟机一直转圈,使用命令行关闭报错 qm stop 155 trying to acquire lock... cant lock file /var/lock/qemu-server/lock-155.conf - got timeout解决 删除lock,然后用命令行重新关闭 rm /var/lock/qemu-serve…...
【Django】 rest_framework接口开发流程及接口功能组成
rest_framework接口开发流程及接口功能组成 使用restframework框架开发接口,方式应该有6、7种,每个人的习惯不同,用的方法也不一样,再次不再一一详述。 我比较常用:ModelSerializerGenericAPIView 原因是用视图函数装饰…...
Kafka Log存储解析以及索引机制
1.概述 在Kafka架构,不管是生产者Producer还是消费者Consumer面向的都是Topic。Topic是逻辑上的概念,而Partition是物理上的概念。每个Partition逻辑上对应一个log文件,该log文件存储是Producer生产的数据。Producer生产的数据被不断追加到该…...
广告电商模式:探索新商业模式,实现三方共赢
随着互联网技术的发展,电商行业正在不断探索新的商业模式。其中,广告电商模式是一种创新的方式,它成功地将广告和电商相结合,实现了三方共赢的局面。一、广告电商模式的定义广告电商模式,顾名思义,是一种将…...
动态线程池框架DynamicTp v1.1.4大版本发布,新增若干实用特性
DynamicTp 简介 DynamicTp 是一个基于配置中心实现的轻量级动态线程池监控管理工具,主要功能可以总结为动态调参、通知报警、运行监控、三方包线程池管理等几大类。 DynamicTp 特性 代码零侵入:我们改变了线程池以往的使用姿势,所有配置均放…...
无线通信——Mesh自组网的多跳性
Mesh的多跳性 Mesh网络具备多跳性。什么是多跳性呢?上面说过,每一个具备Mesh网络的设备都是独立的节点。因此,当我发出一条数据时,这些数据会通过跳跃到达不同的网络节点,数据从一个节点跳到另一个节点,直到…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...
