赞
踩
在进行慢sql评审时,发现测试环境增加了索引生产并没有。然后有些表字段长度也不一样,坑大发了。决定写一个小工具对比一下测试跟生产表结构差异,大致思路连接数据库获取建表语句进行对比,忽略主键自增id。因为测试跟生产主键id自增会有不同,如果建表语句不一致,则需要比对文本高亮显示。在网上copy了一个别人写的高亮算法,生成了一个html预览。直接上代码
- package com.xuyw.test.export;
-
- import com.alibaba.druid.pool.DruidDataSource;
- import org.apache.commons.collections4.MapUtils;
- import org.apache.commons.io.FileUtils;
- import org.springframework.jdbc.core.JdbcTemplate;
-
- import java.io.File;
- import java.io.IOException;
- import java.util.*;
-
-
- /**
- * @author one.xu
- * @version v1.0
- * @description
- * @date 2022/1/5 17:59
- */
- public class DbComparedTest {
- private static JdbcTemplate db1;
- private static JdbcTemplate db2;
-
- static {
- db1 = new JdbcTemplate();
- DruidDataSource dataSource = new DruidDataSource();
- dataSource.setUrl("");
- dataSource.setUsername("");
- dataSource.setPassword("");
- db1.setDataSource(dataSource);
-
-
- db2 = new JdbcTemplate();
- DruidDataSource dataSource2 = new DruidDataSource();
- dataSource2.setUrl("");
- dataSource2.setUsername("");
- dataSource2.setPassword("");
- db2.setDataSource(dataSource2);
- }
- //移除AUTO_INCREMENT
- private static String handTable(String table) {
- return table.replaceAll("AUTO_INCREMENT=\\d+", "").trim();
-
- }
- //文本对比,高亮显示
- public static String getcompareStr(String char1, String char2) {
- String bcolor = "<span style='background-color:yellow;color:red;'>";
- String ecolor = "</span>";
- StringBuffer sb = new StringBuffer();
- char[] a = new char[char1.length()];
- for (int i = 0; i < char1.length(); i++) {
- a[i] = char1.charAt(i);
- }
- char[] b = new char[char2.length()];
- for (int i = 0; i < char2.length(); i++) {
- b[i] = char2.charAt(i);
- }
- // 不同字符集合
- Map<Object, Object> map1 = new HashMap<>();
- // 包含字符集合
- Map<Object, Object> map2 = new HashMap<>();
- for (int i = 0; i < a.length; i++) {
- if (i == a.length - 1) {
- if (i > 1) {
- if (String.valueOf(b).contains(String.valueOf(a[i - 1]) + String.valueOf(a[i]))) {
- map2.put(i - 1, a[i - 1]);
- map2.put(i, a[i]);
- } else {
- map1.put(i, a[i]);
- }
- } else {
- map2.put(i, a[i]);
- }
- } else {
- if (String.valueOf(b).contains(String.valueOf(a[i]) + String.valueOf(a[i + 1]))) {
- if (i > 1) {
- if (String.valueOf(b).contains(String.valueOf(a[i - 1]) + String.valueOf(a[i]))) {
- map2.put(i - 1, a[i - 1]);
- map2.put(i, a[i]);
- }
- } else {
- map2.put(i, a[i]);
- }
- } else {
- if (i > 0) {
- if (String.valueOf(b).contains(String.valueOf(a[i - 1]) + String.valueOf(a[i]))) {
- map2.put(i - 1, a[i - 1]);
- map2.put(i, a[i]);
- } else {
- map1.put(i, a[i]);
- }
- } else {
- map1.put(i, a[i]);
- }
- }
- }
- }
- for (int i = 0; i < a.length; i++) {
- if (map1.get(i) != null) {
- sb.append(bcolor).append(map1.get(i)).append(ecolor);
- } else if (map2.get(i) != null) {
- sb.append(map2.get(i));
- }
- }
- return sb.toString();
- }
-
- public static void main(String[] args) throws IOException {
- //需要比对的数据库名,多个逗号连接
- String dbs = "testDb1,testDb1";
- String tableSql = "select table_name,table_comment FROM information_schema.tables WHERE table_schema=?";
- //忽略比对的表名,多个逗号连接 支持正则
- String ignoreTable = "|(msg_log_\\w+)|(hand_log_\\w+)";
- String tableCreateSql = "show create table ";
- List<Map<String, Object>> tableDiffList = new ArrayList<>();
- Map<String, Object> diffMap;
- Map<String, Integer> dbTableCountMap = new HashMap<>();
- int dbTableCount = 0;
- for (String db : dbs.split(",")) {
- dbTableCount = 0;
- List<Map<String, Object>> tables = db1.queryForList(tableSql, db);
- for (int j = 0; j < tables.size(); j++) {
- String table = tables.get(j).get("table_name").toString();
- if (table.matches(ignoreTable)) {
- continue;
- }
- diffMap = new HashMap<>();
- Map<String, Object> sourceTableMap = db1.queryForMap(tableCreateSql + db + "." + table);
- String sourceTable = handTable(MapUtils.getString(sourceTableMap, "Create Table"));
- diffMap.put("dbName", db);
- diffMap.put("sourceTable", sourceTable);
- Map<String, Object> targetTableMap;
- try {
- targetTableMap = db2.queryForMap(tableCreateSql + db + "." + table);
- } catch (Exception e) {
- dbTableCount = dbTableCount + 1;
- diffMap.put("targetTable", "不存在");
- tableDiffList.add(diffMap);
- continue;
- }
- String targetTable = handTable(MapUtils.getString(targetTableMap, "Create Table"));
- if (sourceTable.equals(targetTable)) {
- continue;
- }
- diffMap.put("targetTable", getcompareStr(targetTable, sourceTable));
- diffMap.put("sourceTable", getcompareStr(sourceTable, targetTable));
- tableDiffList.add(diffMap);
- dbTableCount = dbTableCount + 1;
-
- }
- dbTableCountMap.put(db, dbTableCount);
- }
- StringJoiner html = new StringJoiner("\n");
- html.add("<table style=\"font-size:12px;color:#333333;width:100%;border-width: 1px;border-color: #729ea5;border-collapse: collapse;\" border=\"1\">\n" +
- "<tr><th >数据库名</th><th>源表</th><th>对比表</th></tr>");
-
- for (Map<String, Object> m : tableDiffList) {
- String dbName=m.get("dbName").toString();
- Integer dbTabeCount=dbTableCountMap.get(dbName);
- if(dbTabeCount!=null){
- html.add("<tr> <td rowspan=\""+dbTabeCount+"\">"+dbName+"</td>");
- dbTableCountMap.remove(dbName);
- }
- html.add("<td>\n" +
- "<pre> "+m.get("sourceTable").toString()+" <pre>\n" +
- "</td>");
- html.add("<td>\n" +
- "<pre> "+m.get("targetTable").toString()+" <pre>\n" +
- "</td>");
- html.add("</tr>");
- }
- html.add("</table>");
- FileUtils.writeStringToFile(new File("d:\\DbComparedTest.html"), html.toString());
-
- }
- }
对比效果如下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。