java实现mysql两个数据库对比表结构是否一致

【使用场景】

本地开发完后,增加或者删除了字段,或者修改了字段属性。

如何判定现场环境和本地环境的数据表结构一致性? 肉眼看的话,实在是一个大的工作量,所以开发了此工具。

【类存放路径】

CompareDbMain是主函数。

【具体代码】

public class ColumnEntity {
    private String tableName;
    private String columnName;
    private String columnTypeName;
    private Integer columnDisplaySize;
    private Integer scale;

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getColumnName() {
        return columnName;
    }

    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }

    public String getColumnTypeName() {
        return columnTypeName;
    }

    public void setColumnTypeName(String columnTypeName) {
        this.columnTypeName = columnTypeName;
    }

    public Integer getColumnDisplaySize() {
        return columnDisplaySize;
    }

    public void setColumnDisplaySize(Integer columnDisplaySize) {
        this.columnDisplaySize = columnDisplaySize;
    }

    public Integer getScale() {
        return scale;
    }

    public void setScale(Integer scale) {
        this.scale = scale;
    }
}
public class TableEntity {
    private String tableName; //表名
    private String tableType; //表类型
    private String tableCat; //表所属数据库
    private String tableSchem; //表所属用户名
    private String remarks; //表备注

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getTableType() {
        return tableType;
    }

    public void setTableType(String tableType) {
        this.tableType = tableType;
    }

    public String getTableCat() {
        return tableCat;
    }

    public void setTableCat(String tableCat) {
        this.tableCat = tableCat;
    }

    public String getTableSchem() {
        return tableSchem;
    }

    public void setTableSchem(String tableSchem) {
        this.tableSchem = tableSchem;
    }

    public String getRemarks() {
        return remarks;
    }

    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }
}
import java.sql.*;

/**
 * JDBC工具类
 * 包含数据库连接及关闭数据库资源
 */
public class MysqlDBTools {
    static Connection connection = null;
    static PreparedStatement preparedStatement = null;
    static ResultSet resultSet = null;
    static String DB_URL = "";
    static String DB_USER = "";
    static String DB_PWD = "";

    public MysqlDBTools(String dbUrl, String dbUser, String dbPwd){
        this.DB_URL = dbUrl;
        this.DB_USER = dbUser;
        this.DB_PWD = dbPwd;
    }

    public static Connection getConnection(){
        try{
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PWD);
        }catch (Exception e){
            System.out.println("连接失败!");
            e.printStackTrace();
        }
        return connection;
    }


    public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
        if(resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if(preparedStatement != null){
            try {
                preparedStatement.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if(connection != null){
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}
import java.sql.*;
import java.util.*;

/**
 * 功能
 * 更新可能因为数据表结构发生变化导致程序启动失败
 * 此程序能查找对比两个数据库的表结构以及字段的差异
 * 方便查找问题所在
 */
public class CompareDbMain {

    private static String db_url1 = "jdbc:mysql://xx.xx.xx.xx:3306/udesign?useUnicode=true&characterEncoding=utf8&useSSL=false";
    private static String db_user1 = "root";
    private static String db_pwd1 = "xxx";

    private static String db_url2 = "jdbc:mysql://xx.xx.xx.xx:3306/udesign-v2?useUnicode=true&characterEncoding=utf8&useSSL=false";
    private static String db_user2 = "root";
    private static String db_pwd2 = "xxx";

    public static void main(String[] args) throws Exception{
        System.out.println("[结果说明]");
        System.out.println("1. ++表示A比B多,--表示A比B少,**表示有变化");
        System.out.println("");

        Connection conn1 = new MysqlDBTools(db_url1, db_user1, db_pwd1).getConnection();
        Connection conn2 = new MysqlDBTools(db_url2, db_user2, db_pwd2).getConnection();

        //对比表信息
        List<TableEntity> tables1 = getTables(conn1);
        List<TableEntity> tables2 = getTables(conn2);
        StringBuffer tableRes = compareTable(tables1, tables2);
        System.out.println("[表对比结果]");
        System.out.println(conn1.getCatalog() + " vs " + conn2.getCatalog());
        System.out.println(tableRes);

        StringBuffer columnRes = compareColumn(conn1, conn2, tables1, tables2);
        System.out.println("[表字段对比结果]");
        System.out.println(columnRes);
    }


    public static StringBuffer compareColumn(Connection conn1, Connection conn2, List<TableEntity> tables1, List<TableEntity> table2){
        StringBuffer sb = new StringBuffer();
        for(TableEntity t1: tables1){
            if(tableContains(table2, t1)){
                sb.append("["+ t1.getTableName() +"]"  + "\r\n");
                List<ColumnEntity> columnEntities1 = getColumns(conn1, t1);
                List<ColumnEntity> columnEntities2 = getColumns(conn2, t1);

                for(ColumnEntity c1: columnEntities1){
                    if(columnContains(columnEntities2, c1)){
                        ColumnEntity c2 = getColumnFromList(columnEntities2, c1);
                        if(!c2.getColumnDisplaySize().equals(c1.getColumnDisplaySize())
                        || !c2.getColumnTypeName().equals(c1.getColumnTypeName())
                        || !c2.getScale().equals(c1.getScale())){
                            sb.append("  **" + c2.getColumnName() + "\r\n");
                        }
                        //System.out.println("对比字段属性");
                        continue;
                    }
                }

                for(ColumnEntity c2: columnEntities2){
                    if(!columnContains(columnEntities1, c2)){
                        sb.append("  --" + c2.getColumnName() + "\r\n");
                        continue;
                    }
                }

                for(ColumnEntity c1: columnEntities1){
                    if(!columnContains(columnEntities2, c1)){
                        sb.append("  ++" + c1.getColumnName() + "\r\n");
                        continue;
                    }
                }
            }
        }
        return sb;
    }
    //对比表信息
    public static StringBuffer compareTable(List<TableEntity> tab1, List<TableEntity> tab2){
        StringBuffer sb = new StringBuffer();
        for(TableEntity t1: tab1){
            if(tableContains(tab2, t1)){
                sb.append("    " + t1.getTableName() + "\r\n");
                continue;
            }
        }

        for(TableEntity t2: tab2){
            if(!tableContains(tab1, t2)){
                sb.append("  --" + t2.getTableName() + "\r\n");
                continue;
            }
        }

        for(TableEntity t1: tab1){
            if(!tableContains(tab2, t1)){
                sb.append("  ++" + t1.getTableName() + "\r\n");
                continue;
            }
        }

        return sb;
    }
    //获取字段信息
    public static List<ColumnEntity> getColumns(Connection conn, TableEntity table){
        List<ColumnEntity> columnEntities = new LinkedList<>();
        String sql = "select * from " + table.getTableName();
        try {
            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData meta = rs.getMetaData();
            int columnCount = meta.getColumnCount();
            for (int i = 1; i < columnCount + 1; i++) {
                ColumnEntity columnEntity = new ColumnEntity();
                columnEntity.setColumnName(meta.getColumnName(i).toLowerCase());
                columnEntity.setColumnTypeName( meta.getColumnTypeName(i).toLowerCase());
                columnEntity.setColumnDisplaySize(meta.getColumnDisplaySize(i));
                columnEntity.setScale(meta.getScale(i));
                columnEntity.setTableName(meta.getTableName(i).toLowerCase());

                columnEntities.add(columnEntity);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return columnEntities;
    }

    //获取表信息
    public static List<TableEntity> getTables(Connection conn){
        List<TableEntity> tableEntities = new LinkedList<>();
        try {
            DatabaseMetaData dbMetaData = conn.getMetaData();
            ResultSet rs = dbMetaData.getTables(conn.getCatalog(), null, null,new String[] { "TABLE" });
            while (rs.next()) {// ///TABLE_TYPE/REMARKS
                TableEntity table = new TableEntity();
                table.setTableName(rs.getString("TABLE_NAME").toLowerCase());
                table.setTableType(rs.getString("TABLE_TYPE").toLowerCase());
                table.setTableCat(rs.getString("TABLE_CAT").toLowerCase());
                table.setTableSchem(rs.getString("TABLE_SCHEM")==null? "": rs.getString("TABLE_SCHEM").toLowerCase());
                table.setRemarks(rs.getString("REMARKS").toLowerCase());
                tableEntities.add(table);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return tableEntities;
    }

    //从list里面获取
    public static ColumnEntity getColumnFromList(List<ColumnEntity> columnEntities, ColumnEntity column){
        for(ColumnEntity c: columnEntities){
            if(c.getColumnName().equals(column.getColumnName())
                    && c.getTableName().equals(column.getTableName())){
                return c;
            }
        }

        return null;
    }

    public static boolean tableContains(List<TableEntity> tableEntities, TableEntity table){
        for(TableEntity tab: tableEntities){
            if(tab.getTableName().equals(table.getTableName())){
                return true;
            }
        }

        return  false;
    }

    public static boolean columnContains(List<ColumnEntity> columnEntities, ColumnEntity column){
        for(ColumnEntity tab: columnEntities){
            if(tab.getColumnName().equals(column.getColumnName())
                    && tab.getTableName().equals(column.getTableName())){
                return true;
            }
        }

        return false;
    }
}

结果展示:

[结果说明]
1. ++表示A比B多,--表示A比B少,**表示有变化

[表对比结果]
udesign vs udesign-v2
    b_busi_type
    b_busi_type_l2
    c_config_version
    c_datasource_attr
    c_datasource_attr_set
    c_datasource_change_plan
    c_datasource_corba
    c_datasource_ftp
    c_datasource_info
    c_datasource_jdbc
    c_datasource_kafka
    c_datasource_pipe
    c_datasource_sdtp
    c_datasource_snmp
    c_datasource_socket
    c_datasource_subscribe
    c_dict_data_version
    c_dict_devicetype
    c_dict_net_type
    c_dict_protocol
    c_dict_region
    c_dict_specility
    c_dict_specility_level
    c_dict_vendor
    c_image
    c_image_env
    c_kafka_send_log
    c_omc_device_type
    c_omc_info
    c_omc_ne
    c_omc_net_type
    c_redis_monitor
    c_specility_topic
    collect_schedule_file_log
    collect_schedule_ftp_log
    collect_schedule_ftp_log_d
    collect_schedule_ftp_wait
    collect_schedule_time_log
    collect_stage
    collect_stage_log
    collect_stage_rel
    collect_task
    collect_task_log
    group_info
    pars_data_class
    s_protocoltype
    sys_dict
    sys_dict_item
    ue_component
    ue_component_class
    ue_dir
    ue_dir_type
    ue_etl_task_publish
    ue_stage
    ue_stage_meta_rel
    ue_task
    ue_task_publish
    ue_template
    ue_template_stage
    ue_workspace
  ++kafka

[表字段对比结果]
[b_busi_type]
[b_busi_type_l2]
[c_config_version]
[c_datasource_attr]
[c_datasource_attr_set]
[c_datasource_change_plan]
[c_datasource_corba]
[c_datasource_ftp]
[c_datasource_info]
[c_datasource_jdbc]
[c_datasource_kafka]
[c_datasource_pipe]
[c_datasource_sdtp]
[c_datasource_snmp]
[c_datasource_socket]
[c_datasource_subscribe]
[c_dict_data_version]
[c_dict_devicetype]
[c_dict_net_type]
[c_dict_protocol]
[c_dict_region]
  **county_name
[c_dict_specility]
[c_dict_specility_level]
[c_dict_vendor]
[c_image]
[c_image_env]
[c_kafka_send_log]
[c_omc_device_type]
[c_omc_info]
[c_omc_ne]
[c_omc_net_type]
[c_redis_monitor]
[c_specility_topic]
[collect_schedule_file_log]
[collect_schedule_ftp_log]
[collect_schedule_ftp_log_d]
[collect_schedule_ftp_wait]
[collect_schedule_time_log]
[collect_stage]
[collect_stage_log]
[collect_stage_rel]
[collect_task]
  ++group_names
[collect_task_log]
[group_info]
[pars_data_class]
[s_protocoltype]
[sys_dict]
[sys_dict_item]
[ue_component]
[ue_component_class]
[ue_dir]
[ue_dir_type]
[ue_etl_task_publish]
[ue_stage]
[ue_stage_meta_rel]
[ue_task]
[ue_task_publish]
  --group_names
[ue_template]
[ue_template_stage]
[ue_workspace]

1.多了kafka表

2.c_dict_region county_name字段属性不一致

3. collect_task多了group_names字段

4.ue_task_publish少了group_names字段

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以使用Java Database Connectivity(JDBC) API和SQL语句来比较两个数据库数据是否一致。以下是一个简单的示例: 1. 首先,使用JDBC连接两个数据库。 2. 通过执行SELECT语句从第一个数据库中检索数据,并将结果存储在List或HashMap中。 3. 通过执行SELECT语句从第二个数据库中检索数据,并将结果存储在List或HashMap中。 4. 比较两个数据结构是否相同。如果两个数据库中的数据相同,则这两个数据结构应该是一样的。 下面是一个示例代码: ```java import java.sql.*; import java.util.*; public class DatabaseComparator { private static String url1 = "jdbc:mysql://localhost:3306/database1"; private static String url2 = "jdbc:mysql://localhost:3306/database2"; private static String user = "username"; private static String password = "password"; public static void main(String[] args) { try { // Connect to first database Connection conn1 = DriverManager.getConnection(url1, user, password); Statement stmt1 = conn1.createStatement(); // Retrieve data from first database ResultSet rs1 = stmt1.executeQuery("SELECT * FROM table1"); List<Map<String, Object>> data1 = new ArrayList<>(); while (rs1.next()) { Map<String, Object> row = new HashMap<>(); row.put("column1", rs1.getObject("column1")); row.put("column2", rs1.getObject("column2")); data1.add(row); } // Connect to second database Connection conn2 = DriverManager.getConnection(url2, user, password); Statement stmt2 = conn2.createStatement(); // Retrieve data from second database ResultSet rs2 = stmt2.executeQuery("SELECT * FROM table1"); List<Map<String, Object>> data2 = new ArrayList<>(); while (rs2.next()) { Map<String, Object> row = new HashMap<>(); row.put("column1", rs2.getObject("column1")); row.put("column2", rs2.getObject("column2")); data2.add(row); } // Compare data from both databases if (data1.equals(data2)) { System.out.println("Table data is the same in both databases."); } else { System.out.println("Table data is different in both databases."); } // Close connections rs1.close(); stmt1.close(); conn1.close(); rs2.close(); stmt2.close(); conn2.close(); } catch (SQLException e) { e.printStackTrace(); } } } ``` 请注意,此示例仅比较单个中的数据。如果要比较多个或整个数据库的数据,请编写相应的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早退的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值