【java工具-灵活拉取数据库表结构和数据】

需求:

假设我们现在有一个需求,需要快速拉取数据库的某些表建表语句,和数据,平时做备份之类;

我这边自己写了个工具,不多废话,也不整虚的,

直接看代码:

package com.hugh.javaMybatis.dbWorm;

/**
 * @author Mr.qiuyebai
 * @date 2024/4/1 20:08
 * @VERSION 1.0.0
 * @Describe
 */

import org.springframework.jdbc.BadSqlGrammarException;

import java.io.*;
import java.sql.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GetDbData {

    private static Connection getConnection() throws SQLException, ClassNotFoundException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://127.0.0.1:3306/monitor?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String password = "123456";
        return DriverManager.getConnection(url, user, password);
    }

    public static void main(String[] args) throws FileNotFoundException {
        String inputFile = "/a.txt";
        String relativePath = "target/output.sql";
        File file = new File(relativePath);

        HashSet<String> set = new HashSet<String>();
        set.add("");

        InputStream inputStream = GetDbData.class.getResourceAsStream(inputFile);

        if (inputStream == null) {
            System.out.println("========退出");
            return;
        }
        try (Connection connection = getConnection();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
             PrintWriter writer = new PrintWriter(new FileWriter(file))
        ) {

            String line;
            while ((line = reader.readLine()) != null) {
                if ("".equals(line)) {
                    continue;
                }
                writer.println("-- " + line);
                if (line.toUpperCase().startsWith("SHOW CREATE TABLE")) {
                    try (Statement stmt = connection.createStatement()) {
                        // String tableName = line.split(" ")[3].replace(";", "");
                        String tableName = getTableName(line.toUpperCase(), "TABLE");
                        ResultSet rs = stmt.executeQuery(line);
                        if (rs.next()) {
                            writer.println(rs.getString(2) + ";");
                        }
                    }
                } else if (line.toUpperCase().startsWith("SELECT")) {
                    // 1. 拿到 select 后面,所有字段的类型并存起来,只查一遍,
                    // 2. select * 是全部字段,本功能只涉及select from 一个表
                    // 3. 执行该句sql,拿到结果,
                    // 4. 先打印 a.txt 的那个查询语句(写成注释形式,就是 加上 -- ),
                    // 5. 拼接 INSERT 语句,本质上来说,需要注意 哪些需要 加上 单引号
                    // 6. 最后空两行继续下一个 select 语句处理
                    //String tableName = line.substring(line.toUpperCase().indexOf("FROM") + 5).trim().replace(";", "");
                    String tableName = getTableName(line.toUpperCase(), "FROM");
                    // 获取字段的数据类型
                    Map<String, Integer> columnTypes = getColumnTypes(connection, tableName);
                    try (Statement stmt = connection.createStatement();
                         ResultSet rs = stmt.executeQuery(line)) {
                        ResultSetMetaData metaData = rs.getMetaData();
                        int columnCount = metaData.getColumnCount();

                        // 写入 SELECT 语句作为注释
                        // 对于结果集中的每一行,生成 INSERT 语句
                        while (rs.next()) {
                            StringBuilder columns = new StringBuilder();
                            StringBuilder values = new StringBuilder();
                            for (int i = 1; i <= columnCount; i++) {
                                if (i > 1) {
                                    columns.append(", ");
                                    values.append(", ");
                                }
                                columns.append(metaData.getColumnName(i));
                                int type = columnTypes.getOrDefault(metaData.getColumnName(i), Types.VARCHAR);
                                String value = rs.getString(i);
                                if (type == Types.VARCHAR || type == Types.CHAR || type == Types.LONGVARCHAR || type == Types.TIMESTAMP) {
                                    if (value == null) {
                                        values.append("null");
                                    } else {
                                        values.append("'").append(value.replace("'", "''")).append("'");
                                    }
                                } else {
                                    if (value == null) {
                                        values.append("null");
                                    } else {
                                        values.append(value);
                                    }
                                }
                            }

                            // 换行符号微调
                            // 为什么这样做:节省算力
                            if (set.contains(tableName)) {
                                values.toString().replaceAll("\r\n", "\\r\\n");
                            }

                            writer.printf("INSERT INTO %s (%s) VALUES (%s);\n", tableName, columns, values);
                        }
                    } catch (BadSqlGrammarException e) {
                        System.out.println("=======Bad Sql========");
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("=====Exception!!!====");
                    }
                }
                writer.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取字段类型
     *
     * @param connection
     * @param tableName
     * @return
     */
    private static Map<String, Integer> getColumnTypes(Connection connection, String tableName) {
        Map<String, Integer> columnTypes = new HashMap<>();
        DatabaseMetaData metaData = null;
        try {
            metaData = connection.getMetaData();
            try (ResultSet rs = metaData.getColumns(null, null, tableName, null)) {
                while (rs.next()) {
                    String columnName = rs.getString("COLUMN_NAME");
                    int dataType = rs.getInt("DATA_TYPE");
                    columnTypes.put(columnName, dataType);
                }
            }
            return columnTypes;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取表名字
     *
     * @param line
     * @param keyWord
     * @return
     */
    public static String getTableName(String line, String keyWord) {
        String lowerLine = line.toLowerCase();
        int keyWordIndex = lowerLine.indexOf(keyWord.toLowerCase());
        if (keyWordIndex == -1) {
            // 关键字未找到
            return null;
        }
        // 找到关键字后,截取关键字后的字符串
        String afterKeyWord = line.substring(keyWordIndex + keyWord.length()).trim();

        // 使用正则表达式匹配第一个可能的表名
        // 假设表名由字母、数字、下划线组成,并且可能以反引号包围
        String regex = "^[`]?([a-zA-Z0-9_]+)[`]?";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(afterKeyWord);

        if (matcher.find()) {
            // 返回匹配到的表名
            return matcher.group(1);
        }
        // 未找到合适的匹配
        return null;
    }

}



然后准备这样式的文件,就给导出建表语句和数据;

SHOW CREATE TABLE sys_user;
SELECT * FROM sys_user;

SELECT * FROM sys_dept; 

在这里插入图片描述

完工;
走过路过,点个赞,三连一下哈;

不知不觉,时间过去的很快,
感觉自己最近内耗比较严重,
前段时间找对象来着,被骗了不少米,
真艰难啊,,,
哈哈哈哈,,,
加油吧,好好活着🍀

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch8.x 设置密码

文章目录 一、环境说明二、使用elasticsearch-reset-password工具修改1、elasticsearch-reset-password工具位置2、设置密码 一、环境说明 elasticsearch版本&#xff1a;8.13.0 系统版本&#xff1a;Ubuntu 18.04.6 二、使用elasticsearch-reset-password工具修改 1、elast…

【汇编语言实战】求三个已知数最大值

C语言描述该程序流程&#xff1a; #include <stdio.h> int main() {int a10,b20,c15;//scanf("%d %d",&a,&b);if(a>b){if(a>c){printf("%d",c);}else{printf("%d",a);}}else{if(b>c){printf("%d",b);}else{pr…

Pinctrl子系统、GPIO子系统概念

Pinctrl概念&#xff1a; 无论是哪种芯片&#xff0c;都有类似图 16.1 的结构&#xff1a; 要想让 pinA 、 B 用于 GPIO &#xff0c;需要设置 IOMUX 让它们连接到 GPIO 模块&#xff1b; 要想让 pinA 、 B 用于 I2C &#xff0c;需要设置 IOMUX 让它们连接到 …

Go第三方框架--ants协程池框架

1. 背景介绍 1.1 goroutine ants是站在巨人的肩膀上开发出来的&#xff0c;这个巨人是goroutine&#xff0c;这是连小学生都知道的事儿&#xff0c;那么为什么不继续使用goroutine(以下简称go协程)呢。这是个思考题&#xff0c;希望讲完本文大家可以有个答案。 go协程只涉及用…

python中使用print方法打印时显示颜色

使用说明 在编程中&#xff0c;使用颜色来区分不同类型的输出或突出显示关键信息是一种常见的做法&#xff0c;特别是在调试和日志记录过程中。以下是一些使用颜色输出的常见场景和用途&#xff1a; 调试信息&#xff1a;在调试代码时&#xff0c;可以使用不同颜色来区分不同级…

CSDN 通过博客关注了你

CSDN 通过博客关注了你 前言通过“博文XXX”和“博客”的区别 前言 最近新增粉丝里发现&#xff0c;粉丝来源有不同的方式&#xff1a; 通过博文XXX关注了你 通过你的主页关注了你 通过用户推荐关注了你 通过博客关注了你 通过“博文XXX”和“博客”的区别 通过博文XXX和…

序列化、反序列化:将对象以字节流的方式,进行写入或读取

序列化&#xff1a;将指定对象&#xff0c;以"字节流"的方式写入一个文件或网络中。 反序列化&#xff1a;从一个文件或网络中&#xff0c;以"字节流"的方式读取到对象。 package com.ztt.Demo01;import java.io.FileNotFoundException; import java.io.Fi…

LeetCode-2009. 使数组连续的最少操作数【数组 哈希表 二分查找 滑动窗口】

LeetCode-2009. 使数组连续的最少操作数【数组 哈希表 二分查找 滑动窗口】 题目描述&#xff1a;解题思路一&#xff1a;正难则反滑动窗口解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&#xff1a; 给你一个整数数组 nums 。每一次操作中&#xff0c;你可以将 n…

rabbitmq延迟队列的使用

rabbitmq延迟队列的使用 1、场景&#xff1a; 1.定时发布文章 2.秒杀之后&#xff0c;给30分钟时间进行支付&#xff0c;如果30分钟后&#xff0c;没有支付&#xff0c;订单取消。 3.预约餐厅&#xff0c;提前半个小时发短信通知用户。 A -> 13:00 17:00 16:30 延迟时间&a…

麒麟V10安装Redis6.2.6

1、下载redis安装包 Redis各版本下载&#xff1a;https://download.redis.io/releases/ 2、将下载后的.tar.gz压缩包上传到到服务器自定义文件夹下 3、 解压文件 tar -zxvf redis-6.2.6.tar.gzmv redis-6.2.6 redis4、安装redis 在redis文件夹下输入make指令 cd /opt/redi…

性能测试 —— Jmeter 命令行详细

我们在启动Jmeter时 会看见&#xff1a;Don’t use GUI mode for load testing !, only for Test creation and Test debugging.For load testing, use CLI Mode (was NON GUI) 这句话的意思就是说&#xff0c;不要使用gui模式进行负载测试&#xff0c;gui模式仅仅是创建脚本…

【LeetCode: 628. 三个数的最大乘积 + 排序 + 贪心】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

C++ linked_hash_map按顺序保存的容器

HashMap中不存在保存顺序的机制。而在LinkedHashMap中可以保持两种顺序&#xff0c;分别是插入顺序和访问顺序&#xff0c;这个是可以在LinkedHashMap的初始化方法中进行指定的。相对于访问顺序&#xff0c;按照插入顺序进行编排被使用到的场景更多一些&#xff0c;所以默认是按…

实现鼠标在页面点击出现焦点及大十字星

近段时间&#xff0c;在完成项目进度情况显示时候&#xff0c;用户在操作鼠标时候&#xff0c;显示当鼠标所在位置对应时间如下图所示 代码实现步骤如下&#xff1a; 1.首先引用 jquery.1.7.js 2.再次引用raphael.js 3.然后引用graphics.js 4.最后引用mfocus.js 其中mfocu…

【leetcode面试经典150题】38. 生命游戏(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

蓝桥杯第九届省赛真题代码——彩灯控制器-附详细讲解思路

1. 比赛题目要求 2. 功能实现推荐步骤 首先&#xff0c;添加头文件&#xff0c;搭建最底层的代码&#xff0c;实现基本的流水灯运转与数码管显示rb2的电阻值 然后&#xff0c;进行pwm脉宽调制&#xff0c;实现rb2数值不同&#xff0c;从而灯光亮度不同。并作出数码管的多窗口…

Java GC了解

Jstack找到线程的快照 jvm提供其他命令作用 jps&#xff1a; 虚拟机进程状况工具&#xff0c;类似linux的ps命令 jstat&#xff1a;虚拟机统计信息监视工具&#xff0c;经常看gc情况的会使用到 jinfo: java配置信息工具 jmap&#xff1a; java内存映射工具&#xff0c;dump&am…

别催了!超真实格行5G随身WiFi问答它来了!格行5G随身WiFi靠谱吗? 看完这篇文章你就懂了?

总让我测格行5G随身WiFi&#xff0c;一直催催催。这下别催了&#xff0c;你们要的格行5G随身WiFi真实测评它来了&#xff01;这次着重回答大家最关心&#xff0c;问的最多的几个问题&#xff01; 一、问&#xff1a;格行5G随身WiFi网速怎么样&#xff1f; 答&#xff1a;格行5G…

网络编程套接字(一)

目录 一、源IP和目的IP 二、端口号 三、UDP协议和TCP协议 四、网络字节序 五、socket编程 1、socket 常见接口 2、struct sockaddr结构体 一、源IP和目的IP IP地址是IP协议提供的一种统一的地址格式&#xff0c;它为互联网上的每一个网络和每一台主机分配一个逻辑地址&am…

原子操作和竞争条件

所有系统调用都是以原子操作方式执行的。之所以这么说&#xff0c;是指内核保证了某系统调用中的所有步骤会作为独立操作而一次性加以执行&#xff0c;其间不会为其他进程或线程所中断。原子性是某些操作得以圆满成功的关键所在。特别是它规避了竞争状态&#xff08;race condi…