今天接到一个任务,测试库和开发库不同步,领导让对比2个库的差异,对比原则表名、字段名、字段属性、字段长度、是否为空,刚接手任务,通过查询USER_TAB_COLUMNS表查询出测试库的表字段属性,之后在开发库新建一个表,把数据导入,之后通过为左右连接为null判断是否存在,一查右4000来条数据,之后要一条一条的比较,这根本就做不了,之后想到了写程序达到效果,思路:
demo路径:http://download.csdn.net/download/xionglangs/10224457
1、分别查询到2个库的表名,表子段属性,分别存入MAP中(查询时最好按照表名排序)。
2、第二步,把一个库的表名做为key,表名做value,便利它,如果另外一个map根据key查询不到值,表示此表没有在另外一个库中。
3、之后比较表子段属性,已表名和字段名做key,其余5个属性做值,传入2中查询到的list,过滤key在2中的,就表示2库中都存在表,
但字段维度不同。
4、重复上诉步骤,把比较方位替换。
代码为:
packagecom.sunline.util;
import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author 熊浪 * @Email [email protected] * @Time 2018年1月25日 @此类的作用: */ public class DatabaseUtil { private final static Logger logger = LoggerFactory.getLogger(DatabaseUtil.class); private static final String DRIVER = "oracle.jdbc.OracleDriver"; private static final String URL1 = "jdbc:oracle:thin:@10.22.20.12:1521/UATDEMODB"; private static final String URL2 = "jdbc:oracle:thin:@10.24.0.234:1521/DEVSITDB"; private static final String USERNAME1 = "uat_sungl"; private static final String PASSWORD1 = "uat_sungl"; private static final String USERNAME2 = "sit_sungl"; private static final String PASSWORD2 = "sit_sungl"; private static final String TABLE_INFO = "SELECT DISTINCT TABLE_NAME FROM USER_TABLES"; private static final String TABLE_NAME = "SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE,DATA_LENGTH,NULLABLE FROM USER_TAB_COLUMNS"; private static final String SQL = "SELECT * FROM ";// 数据库操作 static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { logger.error("can not load jdbc driver", e); } } /** * 获取数据库连接 * * @return */ public static Connection getConnection(String url, String userName, String password) { Connection conn = null; try { conn = DriverManager.getConnection(url, userName, password); } catch (SQLException e) { logger.error("get connection failure", e); } return conn; } /** * 关闭数据库连接 * * @param conn */ public static void closeConnection(Connection conn) { if (conn != null) { try { conn.close(); } catch (SQLException e) { logger.error("close connection failure", e); } } } /** * 获取数据库下的所有表名 */ public static MapgetTableInfos(String url, String userName, String password) { Map tableNames = new HashMap (); Connection conn = getConnection(url, userName, password); PreparedStatement pst = null; ResultSet rs = null; try { pst = conn.prepareStatement(TABLE_NAME); rs = pst.executeQuery(); while (rs.next()) { tableNames.put(rs.getString(1) + "=" + rs.getString(2), rs.getString(1) + "=" + rs.getString(2) + "=" + rs.getString(3) + "=" + rs.getString(4) + "=" + rs.getString(5) + "=" + rs.getString(1)); } } catch (SQLException e) { logger.error("getTableNames failure", e); } finally { try { rs.close(); closeConnection(conn); } catch (SQLException e) { logger.error("close ResultSet failure", e); } } return tableNames; } public static Map getTableNames(String url, String userName, String password) { Map tableNames = new HashMap (); Connection conn = getConnection(url, userName, password); PreparedStatement pst = null; ResultSet rs = null; try { pst = conn.prepareStatement(TABLE_INFO); rs = pst.executeQuery(); while (rs.next()) { tableNames.put(rs.getString(1), rs.getString(1)); } } catch (SQLException e) { logger.error("getTableNames failure", e); } finally { try { rs.close(); closeConnection(conn); } catch (SQLException e) { logger.error("close ResultSet failure", e); } } return tableNames; } /** * 获取表中所有字段名称 * * @param tableName 表名 * @return */ public static List getColumnNames(String tableName, String url, String userName, String password) { List columnNames = new ArrayList<>(); // 与数据库的连接 Connection conn = getConnection(url, userName, password); PreparedStatement pStemt = null; String tableSql = SQL + tableName; try { pStemt = conn.prepareStatement(tableSql); // 结果集元数据 ResultSetMetaData rsmd = pStemt.getMetaData(); // 表列数 int size = rsmd.getColumnCount(); for (int i = 0; i < size; i++) { columnNames.add(rsmd.getColumnName(i + 1)); } } catch (SQLException e) { logger.error("getColumnNames failure", e); } finally { if (pStemt != null) { try { pStemt.close(); closeConnection(conn); } catch (SQLException e) { logger.error("getColumnNames close pstem and connection failure", e); } } } return columnNames; } /** * 获取表中所有字段类型 * * @param tableName * @return */ public static List getColumnTypes(String tableName, String url, String userName, String password) { List columnTypes = new ArrayList<>(); // 与数据库的连接 Connection conn = getConnection(url, userName, password); PreparedStatement pStemt = null; String tableSql = SQL + tableName; try { pStemt = conn.prepareStatement(tableSql); // 结果集元数据 ResultSetMetaData rsmd = pStemt.getMetaData(); // 表列数 int size = rsmd.getColumnCount(); for (int i = 0; i < size; i++) { columnTypes.add(rsmd.getColumnTypeName(i + 1)); } Arrays.sort(columnTypes.toArray()); } catch (SQLException e) { logger.error("getColumnTypes failure", e); } finally { if (pStemt != null) { try { pStemt.close(); closeConnection(conn); } catch (SQLException e) { logger.error("getColumnTypes close pstem and connection failure", e); } } } return columnTypes; } public static List > selectTableInfo(Map
uat, Map sit) { Set > uats = uat.entrySet(); Iterator > it = uats.iterator(); Entry infos = null; String uatInfo = "", sitInfo = ""; List > list = new ArrayList
>(); String[] uatArray = null, sitArray = null; while (it.hasNext()) { infos = it.next(); uatInfo = infos.getValue(); sitInfo = sit.get(infos.getKey()); if (!uatInfo.equals(sitInfo)) { List
isDiffent = new ArrayList (); uatArray = uatInfo.split("="); for (int i = 0; i < uatArray.length; i++) { isDiffent.add(uatArray[i]); } if (sitInfo != null) { sitArray = sitInfo.split("="); for (int i = 0; i < sitArray.length; i++) { isDiffent.add(sitArray[i]); } } else { for (int i = 0; i < uatArray.length; i++) { isDiffent.add(""); } } list.add(isDiffent); } } return list; } public static List >selectTableInfo(Map
uat, Map sit, String prefix) { Set > uats = uat.entrySet(); Iterator > it = uats.iterator(); Entry infos = null; String uatInfo = "", sitInfo = ""; List > list = new ArrayList
>(); String[] uatArray = null, sitArray = null; int len=0; while (it.hasNext()) { infos = it.next(); uatInfo = infos.getValue(); sitInfo = sit.get(infos.getKey()); if (!uatInfo.equals(sitInfo)) { uatArray = uatInfo.split("="); if (prefix != null && prefix.contains(uatArray[uatArray.length - 1])) { continue; } List
isDiffent = new ArrayList (); if(prefix!=null) len=uatArray.length-1; else len=uatArray.length; for (int i = 0; i < len; i++) { isDiffent.add(uatArray[i]); } if (sitInfo != null) { sitArray = sitInfo.split("="); for (int i = 0; i < len; i++) { isDiffent.add(sitArray[i]); } } else { for (int i = 0; i < len; i++) { isDiffent.add(""); } } list.add(isDiffent); } } return list; } public static void main(String[] args) { Map uatTable = getTableNames(URL1, USERNAME1, PASSWORD1); Map sitTable = getTableNames(URL2, USERNAME2, PASSWORD2); Map uatInfos = getTableInfos(URL1, USERNAME1, PASSWORD1); Map sitInfos = getTableInfos(URL2, USERNAME2, PASSWORD2); String[] title = {"表名", "字段名", "字段类型", "字段长度", "是否为空", "表名", "字段名", "字段类型", "字段长度", "是否为空"}; String[] infos = {"表名", "字段名", "字段类型", "字段长度", "是否为空", "表名", "字段名", "字段类型", "字段长度", "是否为空"}; List > uatTables = selectTableInfo(uatTable, sitTable, null); List
> infoTables = selectTableInfo(sitTable, uatTable, null); StringBuffer sbOne = new StringBuffer(); StringBuffer sbTwo = new StringBuffer(); for (List
list:uatTables) sbOne.append(list.get(0)+","); for (List list:infoTables) sbTwo.append(list.get(0)+","); ExcelManage.writeInfoToExcel("UAT与SIT表名比较,前面现实UAT", "D:" + File.separator + "长亮", "UAT-SIT_TABLE", "xls", title, uatTables, TableInfoBean.class); ExcelManage.writeInfoToExcel("UAT与UAT字段名比较,前面现实UAT", "D:" + File.separator + "长亮", "UAT-SIT_CLOUMN", "xls", infos, selectTableInfo(uatInfos, sitInfos, sbOne.toString()), SujuInfoBean.class); ExcelManage.writeInfoToExcel("SIT与UAT表名比较,前面现实SIT", "D:" + File.separator + "长亮", "SIT-UAT_TABLE", "xls", title, infoTables, TableInfoBean.class); ExcelManage.writeInfoToExcel("SIT与UAT字段名比较,前面现实SIT", "D:" + File.separator + "长亮", "SIT-UAT_CLOUMN", "xls", infos, selectTableInfo(sitInfos, uatInfos, sbTwo.toString()), SujuInfoBean.class); } }
package com.sunline.util; /** * @author 熊浪 * @Email [email protected] * @Time 2018/1/25 * @此类的作用: */ public class TableInfoBean { private String tableName; public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } }
package com.sunline.util; /** * @author 熊浪 * @Email [email protected] * @Time 2018年1月25日 * @此类的作用: */ public class SujuInfoBean { private String tableNameOne; private String cloumnOne; private String typeOne; private String cloumnLengthOne; private String isOrNullOne; private String tableNameTwo; private String cloumnTwo; private String typeTwo; private String cloumnLengthTwo; private String isOrNullTwo; public String getTableNameOne() { return tableNameOne; } public void setTableNameOne(String tableNameOne) { this.tableNameOne = tableNameOne; } public String getCloumnOne() { return cloumnOne; } public void setCloumnOne(String cloumnOne) { this.cloumnOne = cloumnOne; } public String getTypeOne() { return typeOne; } public void setTypeOne(String typeOne) { this.typeOne = typeOne; } public String getCloumnLengthOne() { return cloumnLengthOne; } public void setCloumnLengthOne(String cloumnLengthOne) { this.cloumnLengthOne = cloumnLengthOne; } public String getIsOrNullOne() { return isOrNullOne; } public void setIsOrNullOne(String isOrNullOne) { this.isOrNullOne = isOrNullOne; } public String getTableNameTwo() { return tableNameTwo; } public void setTableNameTwo(String tableNameTwo) { this.tableNameTwo = tableNameTwo; } public String getCloumnTwo() { return cloumnTwo; } public void setCloumnTwo(String cloumnTwo) { this.cloumnTwo = cloumnTwo; } public String getTypeTwo() { return typeTwo; } public void setTypeTwo(String typeTwo) { this.typeTwo = typeTwo; } public String getCloumnLengthTwo() { return cloumnLengthTwo; } public void setCloumnLengthTwo(String cloumnLengthTwo) { this.cloumnLengthTwo = cloumnLengthTwo; } public String getIsOrNullTwo() { return isOrNullTwo; } public void setIsOrNullTwo(String isOrNullTwo) { this.isOrNullTwo = isOrNullTwo; } }
package com.sunline.util; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbook; /** * @author 熊浪 * @Email [email protected] * @Time 2018年1月25日 @此类的作用: */ public class ExcelManage { public static boolean writeInfoToExcel(String fileTitle, String path, String fileName, String fileType, String[] title, List> list, Class> clazz) { boolean flag = false; try { writer(fileTitle, path, fileName, fileType, insertInfoToBean(list, clazz), title); flag = true; } catch (Exception e) { e.printStackTrace(); } return flag; } private static List