需求:
假设我们现在有一个需求,需要快速拉取数据库的某些表建表语句,和数据,平时做备份之类;
我这边自己写了个工具,不多废话,也不整虚的,
直接看代码:
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;
完工;
走过路过,点个赞,三连一下哈;
不知不觉,时间过去的很快,
感觉自己最近内耗比较严重,
前段时间找对象来着,被骗了不少米,
真艰难啊,,,
哈哈哈哈,,,
加油吧,好好活着🍀