使用Java根据表名导出与导入Sql

news2024/12/23 23:29:40

前言

很粗糙啊,有很多可以优化的地方,而且也不安全,但是临时用还是OK的,我这个是公司里面的单机软件,不联网。

嗨!我是一名社交媒体增长黑客,很高兴能帮助您优化和丰富关于批量作业导出和导入的文章。这个主题相当技术性,但我会将其分解为易于理解的部分。让我们开始吧!

简介

在当今快节奏的数字世界中,高效地导出和导入批量作业对于企业至关重要。批量作业操作涉及处理大量数据,拥有流畅的流程可以节省时间和精力。在本文中,我们将探讨一种基于Java的解决方案,可以让您无缝地导出和导入批量作业。

导出批量作业

提供的代码片段演示了如何使用基于Java的解决方案导出批量作业。以下是代码的详细说明:

  1. exportBatchJobs 方法负责导出批量作业。它使用 StringBuilder 构建每个表的 SQL 语句。

  2. getTableNames 方法使用 SHOW TABLES SQL 查询检索所有表名。

  3. 对于每个表,都会调用 downloadTable 方法。它查询表数据并为每一行生成 SQL 插入语句。

  4. 生成的 SQL 语句会追加到 sqlBuilder 中。

  5. 最后,sqlBuilder 的内容会写入 HTTP 响应,允许用户下载 SQL 文件。

为了优化这段代码,您可以考虑以下改进:

  • 使用 ExecutorServiceFuture 类实现多线程,以并行化导出过程。这可以显著提高性能,特别是在处理大量表时。

  • 探索优化 SQL 生成过程的方法。例如,可以使用批量插入而不是单个插入语句来提高效率。

/**
     * 导出批次作业
     *
     * @author <a href = "mailto:zysicyj@163.com" > 公众号:【程序员朱永胜】 个人博客:【blog.zysicyj.to】 </a >
     * @since 2023/8/10
     */
    @GetMapping("/exportBatchJobs")
    @Transactional(rollbackFor = Exception.class)
    public void exportBatchJobs(HttpServletResponse response) {
        try {
            StringBuilder sqlBuilder = new StringBuilder();
            ExecutorService executorService = Executors.newFixedThreadPool(getTableNames().size());
            List<Future<?>> futures = new ArrayList<>();

            for (String tableName : getTableNames()) {
                Future<?> future = executorService.submit(() -> {
                    try {
                        downloadTable(tableName, sqlBuilder);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                });
                futures.add(future);
            }

            // Wait for all threads to finish
            for (Future<?> future : futures) {
                future.get();
            }

            // Set response headers for file download
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + format(DateUtil.now(), "YYYY-MM-dd HH:mm:ss") + ".sql");

            response.getWriter().write(sqlBuilder.toString());

            executorService.shutdown();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取所有表名
     *
     * @return java.util.List<java.lang.String>
     *
     * @author <a href = "mailto:zysicyj@163.com" > 公众号:【程序员朱永胜】 个人博客:【blog.zysicyj.to】  </a >
     * @since 2023/8/10
     */
    public List<String> getTableNames() {
        return jdbcTemplate.queryForList("SHOW TABLES", String.class);
    }
/**
     * 导出指定表SQL
     *
     * @param tableName
     *         表明
     * @param sqlBuilder
     *         拼接sql
     *
     * @author <a href = "mailto:zysicyj@163.com" > 公众号:【程序员朱永胜】 个人博客:【blog.zysicyj.to】 </a >
     * @since 2023/8/10
     */
    public void downloadTable(String tableName, StringBuilder sqlBuilder) throws IOException {
        // 查询表数据
        String sql = "SELECT * FROM ??";
        List<Map<String, Object>> tableData = jdbcTemplate.queryForList(sql, tableName);
        // 拼接SQL插入语句
        for (Map<String, Object> row : tableData) {
            StringBuilder valuesBuilder = new StringBuilder();
            StringBuilder columnsBuilder = new StringBuilder();

            for (Map.Entry<String, Object> entry : row.entrySet()) {
                columnsBuilder.append(entry.getKey()).append(", ");

                if (entry.getValue() instanceof byte[]) {
                    byte[] binaryData = (byte[]) entry.getValue();
                    String hexString = bytesToHexString(binaryData);
                    valuesBuilder.append("0x").append(hexString).append(", ");
                } else {
                    valuesBuilder.append("'").append(entry.getValue()).append("', ");
                }
            }

            String columns = columnsBuilder.substring(0, columnsBuilder.length() - 2);
            String values = valuesBuilder.substring(0, valuesBuilder.length() - 2);

            sqlBuilder.append("INSERT INTO ").append(tableName).append(" (").append(columns).append(") VALUES (")
                    .append(values).append(");\n");
        }
    }

导出来的就是这种格式的文件

image-20230810221022867

导入批量作业

提供的代码片段演示了如何导入包含批量作业数据的 SQL 文件。以下是代码的详细说明:

  1. executeSqlFile 方法处理导入过程。它接受一个 SQL 文件作为 MultipartFile 并读取其内容。

  2. 使用分号(;)分隔符将 SQL 文件内容拆分为单个语句。

  3. 使用参数化查询执行每个语句,确保安全性并防止 SQL 注入攻击。

  4. 如果 SQL 文件成功执行,则方法返回成功消息。否则,它会记录导入过程中出现的任何错误。

为了优化这段代码,您可以考虑以下改进:

  • 实现错误处理,并提供更详细的错误消息,以帮助用户排除导入过程中可能出现的任何问题。

  • 考虑在执行语句之前验证 SQL 文件内容。这可以帮助防止由格式错误或不兼容的 SQL 语句引起的潜在错误。

/**
     * 导入SQL
     *
     * @return com.nari.common.core.domain.AjaxResult
     *
     * @author <a href = "mailto:zysicyj@163.com" > 公众号:【程序员朱永胜】 个人博客:【blog.zysicyj.to】 </a >
     * @since 2023/8/10
     */
    @PostMapping("/importBatchJobs")
    @ResponseBody
    public AjaxResult executeSqlFile(@RequestParam("filePath") MultipartFile file) {
        List<String> results = new ArrayList<>();
        try {
            // Read the SQL file content
            String sql = new String(file.getBytes());

            // Split the SQL file content into individual statements
            String[] statements = sql.split(";");

            // Execute each statement using parameterized queries
            for (String statement : statements) {
                // Skip empty statements
                if (statement.trim().isEmpty()) {
                    continue;
                }

                // Execute the statement using parameterized queries
                jdbcTemplate.update(statement);
            }

            return AjaxResult.success("SQL file executed successfully");
        } catch (IOException e) {
            results.add(e.getMessage());
        }
        log.info("导入失败的SQL数量:{},{}", results.size(), results);
        return success();
    }

总结

总之,本文探讨了一种基于Java的解决方案,用于导出和导入批量作业。导出过程检索表数据并生成 SQL 插入语句,允许用户下载 SQL 文件。导入过程读取 SQL 文件,将其拆分为单个语句,并使用参数化查询执行这些语句。通过优化代码并实现错误处理,您可以提高批量作业导出和导入功能的效率和可靠性。

希望这篇优化和丰富的文章能帮助您为读者提供有价值的见解。如果您有任何进一步的问题或需要额外的帮助,请随时提问!

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

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

相关文章

openlayers有哪些版本以及区别

vue3openlayer7 openlayer版本介绍 openlayer版本介绍 一、多个项目版本对比 官网首页罗列的几个版本&#xff1a; 包括&#xff1a;v7\v6\v5\v4\v3\v2 两年前使用v6.5.0 2023年7月版本是v7.4.0

CodeForces怎么查找一道题

直接先随便进入一道题的页面&#xff0c;然后改地址栏里面的网址!!! 例如 : 我们要找CF1A这道题的话, 先随便找一道你能看到的题目,如 : 然后将地址栏的158改成1,然后回车就好了

电影院订票选座网站小程序开发(java开源)

搭建一个电影院订票选座网站小程序需要掌握Java语言和相关的Web开发技术&#xff0c;同时需要使用开源框架和库来实现。以下是一个基本的步骤指南&#xff1a; 确定技术栈 首先&#xff0c;需要确定使用的技术栈&#xff0c;以便更好的开展工作。 设计数据库 设计数据库需要…

2023最新Windows编译ffmpeg详细教程,附msys2详细安装配置教程

安装MSYS2 msys2是一款跨平台编译套件&#xff0c;它模拟linux编译环境&#xff0c;支持整合mingw32和mingw64&#xff0c;能很方便的在windows上对一些开源的linux工程进行编译运行。 类似的跨平台编译套件有&#xff1a;msys&#xff0c;cygwin&#xff0c;mingw 优势&…

有人管一管小天才电话手表吗?

作者 | 张未 来源 | 洞见新研社 潮流果然是个圈&#xff0c;曾经风靡2008年的“摇一摇”重回我们的视野当中。 这个对于成年人有些过时的产物&#xff0c;以儿童手表为载体&#xff0c;正入侵着小学生的社交圈&#xff0c;成为儿童的“社交密码”。 “碰一碰”加好友&#x…

如何给a-table增加列宽拖动功能

对于table的列宽设置 相信用过的人都知道&#xff0c;想要设置得很完美&#xff0c;几乎是不现实的&#xff0c;因为总有数据或长或短&#xff0c;那我们应该如何优化它呢&#xff1f;那便是让用户自行拖动列宽&#xff0c;从而能看全table的数据&#xff0c;但是对于antd-vue …

Python进阶-模块和包/random/datetime/ pandas和DataFrame

Python进阶 1. 模块和包 2. random随机数 3. datetime日期模块 4. pandas和DataFrame 1. 模块和包 1.1 模块&#xff1a;就是一个以.py结尾的文件&#xff0c;模块中可以定义函数&#xff0c;类和变量&#xff0c;可执行的代码 Python模块分为&#xff1a;内置模块和第三方模…

利用OneNote文档投递Snake Keylogger的钓鱼活动分析

概述 近期&#xff0c;安天CERT监测到一起利用OneNote文档投递Snake Keylogger窃密木马的网络钓鱼活动。攻击者向用户发送钓鱼邮件&#xff0c;诱导用户打开附件中的OneNote文档&#xff0c;执行OneNote文档中隐藏在图片下方的恶意文件&#xff0c;从而在用户主机上运行Snake …

力扣每日一题(2023年8月) 更新中~

2023年8月——每日一题 1、8月6日 24. 两两交换链表中的节点 思路&#xff1a;直接模拟 使用虚拟头结点&#xff0c;初始时cur指向虚拟头结点&#xff0c;然后执行三步骤&#xff0c;具体见代码 C代码 /*** Definition for singly-linked list.* struct ListNode {* in…

【论文阅读】基于深度学习的时序预测——Autoformer

系列文章链接 论文一&#xff1a;2020 Informer&#xff1a;长时序数据预测 论文二&#xff1a;2021 Autoformer&#xff1a;长序列数据预测 论文链接&#xff1a;https://arxiv.org/abs/2106.13008 github链接&#xff1a;https://github.com/thuml/Autoformer 解读参考&…

数据库签名的那些事儿

写在前面&#xff0c;关于签名的应用场景 除了我们后端经常使用的接口签名来校验数据这些常见的场景&#xff0c;对于数据安全性要求比较严格的业务来说&#xff0c;大部分落库的核心数据 也都需要签名&#xff0c;为啥? 因为怕数据库的数据被篡改数据或者被攻击了&#xff0c…

【C# 基础精讲】List 集合的使用

在C#中&#xff0c;List<T>是一种非常常用的泛型集合类&#xff0c;用于存储一组相同类型的元素。List<T>具有动态调整大小的能力&#xff0c;可以方便地添加、删除、查找和修改元素&#xff0c;非常灵活和高效。本文将详细介绍List<T>集合的使用方法&#x…

教你如何实现接口防刷

教你如何实现接口防刷 前言 我们在浏览网站后台的时候&#xff0c;假如我们频繁请求&#xff0c;那么网站会提示 “请勿重复提交” 的字样&#xff0c;那么这个功能究竟有什么用呢&#xff0c;又是如何实现的呢&#xff1f; 其实这就是接口防刷的一种处理方式&#xff0c;通…

一台电脑B用网线共享另外一台电脑A的WiFi网络,局域网其它电脑C怎么访问电脑B服务

环境: 电脑A:联想E14笔记本 系统:WIN10 专业版 局域网IP:192.168.14.111 共享IP:192.168.137.1 电脑B:HP 288pro 台式机 Ubuntu20.04 系统:共享IP:192.168.137.180 电脑A正常连接WIFI,电脑B没有WIFI只有,有线网口,共享电脑A的无线网 (还有一种桥接网络不在本…

[FPAG开发]使用Vivado创建第一个程序

1 打开Vivado软件&#xff0c;新建项目 选择一个纯英文路径 选择合适的型号 产品型号ZYNQ-7010xc7z010clg400-1ZYNQ-7020xc7z010clg400-2 如果型号选错&#xff0c;可以单击这里重新选择 2 创建工程源文件 可以看到文件创建成功 双击文件打开&#xff0c;插入代码 modul…

腾讯云轻量服务器和云服务器的CPU处理器有差别吗?

腾讯云轻量应用服务器和CVM云服务器的CPU处理器性能有差别吗&#xff1f;创建轻量应用服务器时不支持指定底层物理服务器的CPU型号&#xff0c;腾讯云将随机分配满足套餐规格的物理CPU型号&#xff0c;通常优先选择较新代次的CPU型号。而云服务器CVM的CPU处理器型号、主频都是有…

数据库--MySQL

一、什么是范式&#xff1f; 范式是数据库设计时遵循的一种规范&#xff0c;不同的规范要求遵循不同的范式。 最常用的三大范式 第一范式(1NF)&#xff1a;属性不可分割&#xff0c;即每个属性都是不可分割的原子项。(实体的属性即表中的列) 第二范式(2NF)&#xff1a;满足…

elementui表格数据加载即勾选

搜索关键字&#xff1a;elementui表格数据加载即勾选|elementui表格勾选 1、关键点&#xff1a; 需要使用watch和nextTick,直接参考官方案例&#xff0c;在数据返回时候设置勾选不好使。 2、表格定义 <el-table :height"570" :data"roleTableData" st…

小疆智控EtherCAT转PROFINET连接零差云控驱动器接入Profinet网络

西门子S7-1200/1500系列的PLC&#xff0c;需要连接带EtherCAT的通讯功能的伺服驱动器等设备。西门子的PLC采用PROFINET实时以太网通讯协议&#xff0c;要连接EtherCAT的设备&#xff0c;就必须进行通讯协议转换。小疆GW-PN-ECATM系列的网关提供了&#xff0c;快速可行的解决方案…

FreeRTOS( 任务与中断优先级,临界保护)

资料来源于硬件家园&#xff1a;资料汇总 - FreeRTOS实时操作系统课程(多任务管理) 目录 一、中断优先级 1、NVIC基础知识 2、FreeRTOS配置NVIC 3、SVC、PendSV、Systick中断 4、不受FreeRTOS管理的中断 5、STM32CubeMX配置 二、任务优先级 1、任务优先级说明 2、任务…