欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Java編寫一個數(shù)據(jù)庫比較工具類

 更新時間:2023年07月21日 09:39:47   作者:zyqok  
這篇文章主要為大家詳細(xì)介紹了如何基于Java編寫一個數(shù)據(jù)庫比較工具類,其中比較結(jié)果會以現(xiàn)數(shù)據(jù)庫的視角說明,感興趣的小伙伴可以了解一下

數(shù)據(jù)庫比較工具類

溫馨提示

(1)如果想知道現(xiàn)數(shù)據(jù)庫和原數(shù)據(jù)庫有哪些區(qū)別,則原數(shù)據(jù)庫配置 old,現(xiàn)數(shù)據(jù)庫配置 now;

(2)比較結(jié)果以現(xiàn)數(shù)據(jù)庫的視角說明,如:提示新增 xxx 表,則表示現(xiàn)數(shù)據(jù)庫有,原數(shù)據(jù)庫沒有,反之;

(3)整個比較過程中,并不會對兩個數(shù)據(jù)庫造成任何影響,可放心使用;

(4)配置好兩個數(shù)據(jù)庫后,直接運(yùn)行本類中的 main() 方法即可,最終比較結(jié)果將以 json 的格式直接輸出在控制臺。

完整代碼

package sql;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.sql.*;
import java.util.*;
/**
 * 數(shù)據(jù)庫比較工具類
 * 溫馨提示:
 * (1)如果想知道現(xiàn)數(shù)據(jù)庫和原數(shù)據(jù)庫有哪些區(qū)別,則原數(shù)據(jù)庫配置 old,現(xiàn)數(shù)據(jù)庫配置 now;
 * (2)比較結(jié)果以現(xiàn)數(shù)據(jù)庫的視角說明,如:提示新增 xxx 表,則表示現(xiàn)數(shù)據(jù)庫有,原數(shù)據(jù)庫沒有,反之;
 * (3)整個比較過程中,并不會對兩個數(shù)據(jù)庫造成任何影響,可放心使用;
 * (4)配置好兩個數(shù)據(jù)庫后,直接運(yùn)行本類中的 main() 方法即可,最終比較結(jié)果將以 json 的格式直接輸出在控制臺。
 *
 * @author Yuanqiang.Zhang
 * @since 2023/7/3
 */
@Data
public class CompareDataBaseUtils {
    public static Map<String, String> old;
    public static Map<String, String> now;
    static {
        // 原數(shù)據(jù)庫
        old = new HashMap<>();
        old.put(Constant.ip, "127.0.0.1");
        old.put(Constant.port, "3306");
        old.put(Constant.dataBaseName, "zyq_test");
        old.put(Constant.userName, "root");
        old.put(Constant.password, "root123");
        old.put(Constant.description, "原數(shù)據(jù)庫");
        // 現(xiàn)數(shù)據(jù)庫
        now = new HashMap<>();
        now.put(Constant.ip, "127.0.0.1");
        now.put(Constant.port, "3306");
        now.put(Constant.dataBaseName, "zyq_test2");
        now.put(Constant.userName, "root");
        now.put(Constant.password, "root123");
        now.put(Constant.description, "現(xiàn)數(shù)據(jù)庫");
    }
    /**
     * 【主方法】配置好數(shù)據(jù)源后直接執(zhí)行即可
     */
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        print("比較中,請等待...");
        JSONObject compareResult = compareDataBase();
        if (Objects.nonNull(compareResult)) {
            print(String.format("比較完成,累計(jì)耗時%s毫秒", (System.currentTimeMillis() - startTime)));
            print("最終比較結(jié)果如下:");
            print(compareResult.toString());
        }
    }
    public static JSONObject compareDataBase() {
        Connection oldConn = getConnection(old);
        Connection nowConn = getConnection(now);
        if (Objects.isNull(oldConn) || Objects.isNull(nowConn)) {
            return null;
        }
        JSONObject oldTables = getCompareTable(old, oldConn);
        JSONObject nowTables = getCompareTable(now, nowConn);
        Set<String> allTableNames = new HashSet<>();
        allTableNames.addAll(oldTables.keySet());
        allTableNames.addAll(nowTables.keySet());
        List<String> nowMoreTableNames = new ArrayList<>();
        List<String> nowLessTableNames = new ArrayList<>();
        List<String> commonTableNames = new ArrayList<>();
        for (String tableName : allTableNames) {
            boolean existOld = oldTables.containsKey(tableName);
            boolean existNow = nowTables.containsKey(tableName);
            if (existNow && existOld) {
                commonTableNames.add(tableName);
            } else {
                if (existNow) {
                    nowMoreTableNames.add(tableName);
                } else {
                    nowLessTableNames.add(tableName);
                }
            }
        }
        // 表相關(guān)修改
        JSONObject compare = new JSONObject(new LinkedHashMap<>());
        compare.put(Constant.more_tables, nowMoreTableNames);
        compare.put(Constant.less_tables, nowLessTableNames);
        // 獲取相同兩張表的比較結(jié)果
        JSONObject changeTables = new JSONObject(new LinkedHashMap<>());
        for (String commonTableName : commonTableNames) {
            JSONObject oldInfo = oldTables.getJSONObject(commonTableName);
            JSONObject nowInfo = nowTables.getJSONObject(commonTableName);
            JSONObject compareInfo = getCompareInfo(oldInfo, nowInfo);
            Boolean changed = compareInfo.getBoolean(Constant.changed);
            if (changed) {
                compareInfo.remove(Constant.changed);
                changeTables.put(commonTableName, compareInfo);
            }
        }
        compare.put(Constant.update_tables, changeTables);
        return compare;
    }
    /**
     * 獲取老表和新表之間的比較結(jié)果
     */
    public static JSONObject getCompareInfo(JSONObject old, JSONObject now) {
        // 表信息比較
        JSONObject oldBasic = old.getJSONObject(Constant.basics);
        JSONObject nowBasic = now.getJSONObject(Constant.basics);
        JSONArray basicCompareResult = compareSameFieldsObject(oldBasic, nowBasic);
        // 表字段比較
        JSONObject oldFields = old.getJSONObject(Constant.fields);
        JSONObject nowFields = now.getJSONObject(Constant.fields);
        Set<String> allFields = new HashSet<>();
        allFields.addAll(oldFields.keySet());
        allFields.addAll(nowFields.keySet());
        JSONArray nowMoreFields = new JSONArray();
        JSONArray nowLessFields = new JSONArray();
        JSONArray commonFields = new JSONArray();
        for (String field : allFields) {
            boolean existOld = oldFields.containsKey(field);
            boolean existNow = nowFields.containsKey(field);
            if (existOld && existNow) {
                commonFields.add(field);
            } else {
                if (existNow) {
                    nowMoreFields.add(field);
                } else {
                    nowLessFields.add(field);
                }
            }
        }
        // 相同字段更新比較
        JSONObject fieldsCompareResult = new JSONObject(new LinkedHashMap<>());
        for (Object field : commonFields) {
            String fileName = field.toString();
            JSONObject oldField = oldFields.getJSONObject(fileName);
            JSONObject nowField = nowFields.getJSONObject(fileName);
            JSONArray commonResultArray = compareSameFieldsObject(oldField, nowField);
            if (!commonResultArray.isEmpty()) {
                fieldsCompareResult.put(fileName, commonResultArray);
            }
        }
        // 字段變更信息
        boolean fieldChanged = !nowMoreFields.isEmpty() || !nowLessFields.isEmpty() || !fieldsCompareResult.isEmpty();
        JSONObject fieldsResult = new JSONObject(new LinkedHashMap<>());
        if (!nowMoreFields.isEmpty()) {
            fieldsResult.put(Constant.more_fields, nowMoreFields);
        }
        if (!nowLessFields.isEmpty()) {
            fieldsResult.put(Constant.less_fields, nowLessFields);
        }
        if (!fieldsCompareResult.isEmpty()) {
            fieldsResult.put(Constant.update_fields, fieldsCompareResult);
        }
        // 基礎(chǔ)變更信息
        boolean basicChanged = !basicCompareResult.isEmpty();
        // 總變更信息
        boolean changed = fieldChanged || basicChanged;
        // 字段比較結(jié)果
        JSONObject compareResult = new JSONObject(new LinkedHashMap<>());
        if (basicChanged) {
            compareResult.put(Constant.table_change_info, basicCompareResult);
        }
        if (fieldChanged) {
            compareResult.put(Constant.field_change_info, fieldsResult);
        }
        compareResult.put(Constant.changed, changed);
        return compareResult;
    }
    /**
     * 比較新老兩個相同屬性的對象
     *
     * @param oldObj 老對象
     * @param nowObj 新對象
     * @return 比較結(jié)果
     */
    private static JSONArray compareSameFieldsObject(JSONObject oldObj, JSONObject nowObj) {
        Set<String> keys = oldObj.keySet();
        JSONArray array = new JSONArray();
        String oldDesc = old.get(Constant.description);
        String nowDesc = now.get(Constant.description);
        for (String key : keys) {
            String oldValue = oldObj.getString(key);
            String nowValue = nowObj.getString(key);
            boolean same;
            if (Objects.isNull(oldValue)) {
                same = Objects.isNull(nowValue);
            } else {
                same = oldValue.equals(nowValue);
            }
            if (!same) {
                JSONObject diff = new JSONObject(new LinkedHashMap<>());
                diff.put(Constant.change_dimension, key);
                diff.put(oldDesc, oldValue);
                diff.put(nowDesc, nowValue);
                array.add(diff);
            }
        }
        return array;
    }
    /**
     * 獲取所有表字段屬性
     *
     * @param dataSource 數(shù)據(jù)源
     * @return 表信息
     */
    public static JSONObject getCompareTable(Map<String, String> dataSource, Connection conn) {
        // 獲取數(shù)據(jù)庫所有表基礎(chǔ)信息
        JSONObject basics = getAllTableList(conn);
        String dbName = dataSource.get(Constant.dataBaseName);
        String desc = dataSource.get(Constant.description);
        int tableCount = 0;
        int tableTotal = basics.size();
        // 獲取每張表的每個字段詳情
        JSONObject tables = new JSONObject(new LinkedHashMap<>());
        for (String tableName : basics.keySet()) {
            tableCount++;
            JSONObject table = new JSONObject(new LinkedHashMap<>());
            table.put(Constant.basics, basics.getJSONObject(tableName));
            JSONObject fields = getTableFields(conn, dbName, tableName);
            table.put(Constant.fields, fields);
            String info = String.format("[%s][%s/%s][%s]解析完成,共%s個字段。",
                    desc, tableCount, tableTotal, tableName, fields.size());
            print(info);
            tables.put(tableName, table);
        }
        return tables;
    }
    /**
     * 獲取數(shù)據(jù)源屬性
     *
     * @param conn         數(shù)據(jù)庫連接
     * @param dataBaseName 數(shù)據(jù)庫名稱
     * @param tableName    表名稱
     * @return 該表的所有字段信息
     */
    private static JSONObject getTableFields(Connection conn, String dataBaseName, String tableName) {
        String sql = "SELECT * FROM information_schema.columns WHERE table_schema = '" + dataBaseName + "' AND table_name = '" + tableName + "'";
        JSONObject columns = new JSONObject(new LinkedHashMap<>());
        try {
            Statement stat = conn.createStatement();
            ResultSet rs = stat.executeQuery(sql);
            while (rs.next()) {
                JSONObject column = new JSONObject(new LinkedHashMap<>());
                String name = rs.getString("COLUMN_NAME");
                column.put(Constant.column_name, name);
                column.put(Constant.column_comment, rs.getString("COLUMN_COMMENT"));
                column.put(Constant.column_is_nullable, rs.getString("IS_NULLABLE"));
                column.put(Constant.column_type, rs.getString("COLUMN_TYPE"));
                column.put(Constant.column_collation, rs.getString("COLLATION_NAME"));
                column.put(Constant.column_key, rs.getString("COLUMN_KEY"));
                column.put(Constant.column_extra, rs.getString("EXTRA"));
                columns.put(name, column);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return columns;
    }
    /**
     * 獲取數(shù)據(jù)庫鏈接
     *
     * @param map 數(shù)據(jù)源
     * @return Connection
     */
    private static Connection getConnection(Map<String, String> map) {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            String url = String.format("jdbc:mysql://%s:%s/%s",
                    map.get(Constant.ip), map.get(Constant.port), map.get(Constant.dataBaseName));
            return DriverManager.getConnection(url, map.get(Constant.userName), map.get(Constant.password));
        } catch (Exception e) {
            System.err.printf("[%s]連接失敗,請檢查配置是否正確!%n", map.get(Constant.description));
            return null;
        }
    }
    /**
     * 獲取所有數(shù)據(jù)表名
     *
     * @param conn 數(shù)據(jù)庫鏈接信息
     * @return Map<表名, 備注>
     */
    private static JSONObject getAllTableList(Connection conn) {
        String sql = "SHOW TABLE status";
        JSONObject basics = new JSONObject(new LinkedHashMap<>());
        try {
            Statement stat = conn.createStatement();
            ResultSet rs = stat.executeQuery(sql);
            while (rs.next()) {
                JSONObject basic = new JSONObject(new LinkedHashMap<>());
                String name = rs.getString("Name");
                basic.put(Constant.table_name, name);
                basic.put(Constant.table_engine, rs.getString("Engine"));
                basic.put(Constant.table_comment, rs.getString("Comment"));
                basic.put(Constant.table_collation, rs.getString("Collation"));
                basics.put(name, basic);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return basics;
    }
    private static JSONObject getTableIndexes(Connection conn, String tableName) {
        String sql = "SHOW INDEX FROM " + tableName;
        JSONObject columns = new JSONObject(new LinkedHashMap<>());
        try {
            Statement stat = conn.createStatement();
            ResultSet rs = stat.executeQuery(sql);
            while (rs.next()) {
                JSONObject column = new JSONObject(new LinkedHashMap<>());
                String name = rs.getString("COLUMN_NAME");
                column.put(Constant.column_name, name);
                column.put(Constant.column_comment, rs.getString("COLUMN_COMMENT"));
                column.put(Constant.column_is_nullable, rs.getString("IS_NULLABLE"));
                column.put(Constant.column_type, rs.getString("COLUMN_TYPE"));
                column.put(Constant.column_collation, rs.getString("COLLATION_NAME"));
                column.put(Constant.column_key, rs.getString("COLUMN_KEY"));
                column.put(Constant.column_extra, rs.getString("EXTRA"));
                columns.put(name, column);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return columns;
    }
    /**
     * 輸出打印
     *
     * @param msg 打印信息
     */
    private static void print(String msg) {
        System.out.println(msg);
    }
    /**
     * 工具類中含的常量(為方便閱讀,本工具類中與輸入無相關(guān)的常量字段均采用下劃線小寫)
     */
    private static class Constant {
        // 數(shù)據(jù)源配置常量鍵
        public static final String ip = "ip";
        public static final String port = "port";
        public static final String dataBaseName = "dataBaseName";
        public static final String userName = "userName";
        public static final String password = "password";
        public static final String description = "description";
        // 代碼邏輯常量
        public static final String basics = "basics";
        public static final String fields = "fields";
        public static final String changed = "changed";
        // 比較結(jié)果鍵名(其他)
        public static final String table_change_info = "表信息變更";
        public static final String field_change_info = "表字段變更";
        public static final String more_tables = "新增的表";
        public static final String less_tables = "減少的表";
        public static final String update_tables = "變更的表";
        public static final String more_fields = "新增的字段";
        public static final String less_fields = "減少的字段";
        public static final String update_fields = "變更的字段";
        public static final String change_dimension = "變更維度";
        // 比較結(jié)果鍵名(表信息)
        public static final String table_name = "名稱";
        public static final String table_engine = "引擎";
        public static final String table_comment = "備注";
        public static final String table_collation = "字符集";
        // 比較結(jié)果鍵名(字段信息)
        public static final String column_name = "名稱";
        public static final String column_comment = "備注";
        public static final String column_is_nullable = "是否可空";
        public static final String column_type = "數(shù)據(jù)類型";
        public static final String column_collation = "字符集";
        public static final String column_key = "鍵類型";
        public static final String column_extra = "額外信息";
    }
}

以上就是基于Java編寫一個數(shù)據(jù)庫比較工具類的詳細(xì)內(nèi)容,更多關(guān)于Java數(shù)據(jù)庫比較工具類的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java值傳遞之swap()方法不能交換的解決

    Java值傳遞之swap()方法不能交換的解決

    這篇文章主要介紹了Java值傳遞之swap()方法不能交換的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java生成PDF文件的實(shí)例代碼

    Java生成PDF文件的實(shí)例代碼

    Java生成PDF文件的實(shí)例代碼,需要的朋友可以參考一下
    2013-05-05
  • 手把手教你寫一個SpringBoot+gRPC服務(wù)

    手把手教你寫一個SpringBoot+gRPC服務(wù)

    本文將在本地環(huán)境下搭建gRPC客戶端和服務(wù)端,并成功建立通訊發(fā)送消息的方式,從而幫助大家深入了解gRPC在Spring Boot項(xiàng)目中的應(yīng)用,有需要的小伙伴可以參考下
    2023-12-12
  • java Long==Long有趣的現(xiàn)象詳解

    java Long==Long有趣的現(xiàn)象詳解

    這篇文章主要給大家介紹了關(guān)于java Long==Long有趣的現(xiàn)象的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • Spring Boot實(shí)現(xiàn)郵件服務(wù)(附:常見郵箱的配置)

    Spring Boot實(shí)現(xiàn)郵件服務(wù)(附:常見郵箱的配置)

    這篇文章主要給大家介紹了關(guān)于Spring Boot實(shí)現(xiàn)郵件服務(wù)的相關(guān)資料,文中還附上了常見郵箱的配置,通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • Java代碼中與Lua相互調(diào)用實(shí)現(xiàn)詳解

    Java代碼中與Lua相互調(diào)用實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了Java代碼中與Lua相互調(diào)用實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 詳解如何更改SpringBoot TomCat運(yùn)行方式

    詳解如何更改SpringBoot TomCat運(yùn)行方式

    這篇文章主要介紹了詳解如何更改SpringBoot TomCat運(yùn)行方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java基礎(chǔ)教程之對象引用

    Java基礎(chǔ)教程之對象引用

    這篇文章主要介紹了Java基礎(chǔ)教程之對象引用,“對象引用”(object reference)是一個重要重要概念,涉及內(nèi)存,需要的朋友可以參考下
    2014-09-09
  • 老生常談JVM的內(nèi)存溢出說明及參數(shù)調(diào)整

    老生常談JVM的內(nèi)存溢出說明及參數(shù)調(diào)整

    下面小編就為大家?guī)硪黄仙U凧VM的內(nèi)存溢出說明及參數(shù)調(diào)整。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java新手學(xué)習(xí)之IO流的簡單使用

    Java新手學(xué)習(xí)之IO流的簡單使用

    IO主要用于設(shè)備之間的數(shù)據(jù)傳輸,Java將操作數(shù)據(jù)流的功能封裝到了IO包中,這篇文章主要給大家介紹了關(guān)于Java新手學(xué)習(xí)之IO流簡單使用的相關(guān)資料,需要的朋友可以參考下
    2021-10-10

最新評論