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

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

前言

很粗糙啊,有很多可以优化的地方,而且也不安全,但是临时用还是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");
        }
    }

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

导入批量作业

提供的代码片段演示了如何导入包含批量作业数据的 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 文件,将其拆分为单个语句,并使用参数化查询执行这些语句。通过优化代码并实现错误处理,您可以提高批量作业导出和导入功能的效率和可靠性。

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

相关文章
|
15天前
|
缓存 easyexcel Java
Java EasyExcel 导出报内存溢出如何解决
大家好,我是V哥。使用EasyExcel进行大数据量导出时容易导致内存溢出,特别是在导出百万级别的数据时。以下是V哥整理的解决该问题的一些常见方法,包括分批写入、设置合适的JVM内存、减少数据对象的复杂性、关闭自动列宽设置、使用Stream导出以及选择合适的数据导出工具。此外,还介绍了使用Apache POI的SXSSFWorkbook实现百万级别数据量的导出案例,帮助大家更好地应对大数据导出的挑战。欢迎一起讨论!
116 1
|
1月前
|
SQL 关系型数据库 MySQL
数据库导入SQL文件:全面解析与操作指南
在数据库管理中,将SQL文件导入数据库是一个常见且重要的操作。无论是迁移数据、恢复备份,还是测试和开发环境搭建,掌握如何正确导入SQL文件都至关重要。本文将详细介绍数据库导入SQL文件的全过程,包括准备工作、操作步骤以及常见问题解决方案,旨在为数据库管理员和开发者提供全面的操作指南。一、准备工作在导
159 0
|
4天前
|
Java API Apache
|
8天前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
20 4
|
28天前
|
SQL 关系型数据库 Shell
SQL整库导出语录及其实用技巧与方法
在数据库管理和备份恢复过程中,整库导出是一项至关重要的任务
|
30天前
|
SQL Oracle 关系型数据库
SQL整库导出语录:全面解析与高效执行策略
在数据库管理和维护过程中,整库导出是一项常见的需求,无论是为了备份、迁移还是数据分析,掌握如何高效、准确地导出整个数据库至关重要
|
30天前
|
SQL 存储 关系型数据库
SQL文件导入MySQL数据库的详细指南
数据库中的数据转移是一项常规任务,无论是在数据迁移过程中,还是在数据备份、还原场景中,导入导出SQL文件显得尤为重要。特别是在使用MySQL数据库时,如何将SQL文件导入数据库是一项基本技能。本文将详细介绍如何将SQL文件导入MySQL数据库,并提供一个清晰、完整的步骤指南。这篇文章的内容字数大约在
61 1
|
2月前
|
存储 Java
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
44 2
|
2月前
|
Java Apache Maven
Java中使用poi+poi-tl实现根据模板导出word文档
这个过程不仅简化了文档生成的工作,而且保证了生成文档的一致性与准确性,特别适合于那些需要生成大量文档的自动化场景。通过以上步骤,Java开发人员可以实现高效、可靠的Word文档导出功能。
1132 0
|
3月前
|
SQL 存储 JSON
【Azure 存储服务】Blob中数据通过Stream Analytics导出到SQL/Cosmos DB
【Azure 存储服务】Blob中数据通过Stream Analytics导出到SQL/Cosmos DB