怎么对比2个数据库的差异
2018-01-25 19:15
225 查看
今天接到一个任务,测试库和开发库不同步,领导让对比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;
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 xiongl@sunline.cn * @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 Map<String, String> getTableInfos(String url, String userName, String password) { Map<String, String> tableNames = new HashMap<String, String>(); 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<String, String> getTableNames(String url, String userName, String password) { Map<String, String> tableNames = new HashMap<String, String>(); 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<String> getColumnNames(String tableName, String url, String userName, String password) { List<String> 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<String> getColumnTypes(String tableName, String url, String userName, String password) { List<String> 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<List<String>> selectTableInfo(Map<String, String> uat, Map<String, String> sit) { Set<Entry<String, String>> uats = uat.entrySet(); Iterator<Entry<String, String>> it = uats.iterator(); Entry<String, String> infos = null; String uatInfo = "", sitInfo = ""; List<List<String>> list = new ArrayList<List<String>>(); String[] uatArray = null, sitArray = null; while (it.hasNext()) { infos = it.next(); uatInfo = infos.getValue(); sitInfo = sit.get(infos.getKey()); if (!uatInfo.equals(sitInfo)) { List<String> isDiffent = new ArrayList<String>(); 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<List<String>>selectTableInfo(Map<String, String> uat, Map<String, String> sit, String prefix) { Set<Entry<String, String>> uats = uat.entrySet(); Iterator<Entry<String, String>> it = uats.iterator(); Entry<String, String> infos = null; String uatInfo = "", sitInfo = ""; List<List<String>> list = new ArrayList<List<String>>(); 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<String> isDiffent = new ArrayList<String>(); 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<String, String> uatTable = getTableNames(URL1, USERNAME1, PASSWORD1); Map<String, String> sitTable = getTableNames(URL2, USERNAME2, PASSWORD2); Map<String, String> uatInfos = getTableInfos(URL1, USERNAME1, PASSWORD1); Map<String, String> sitInfos = getTableInfos(URL2, USERNAME2, PASSWORD2); String[] title = {"表名", "字段名", "字段类型", "字段长度", "是否为空", "表名", "字段名", "字段类型", "字段长度", "是否为空"}; String[] infos = {"表名", "字段名", "字段类型", "字段长度", "是否为空", "表名", "字段名", "字段类型", "字段长度", "是否为空"}; List<List<String>> uatTables = selectTableInfo(uatTable, sitTable, null); List<List<String>> infoTables = selectTableInfo(sitTable, uatTable, null); StringBuffer sbOne = new StringBuffer(); StringBuffer sbTwo = new StringBuffer(); for (List<String> list:uatTables) sbOne.append(list.get(0)+","); for (List<String> 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 xiongl@sunline.cn * @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 xiongl@sunline.cn * @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 xiongl@sunline.cn * @Time 2018年1月25日 @此类的作用: */ public class ExcelManage { public static boolean writeInfoToExcel(String fileTitle, String path, String fileName, String fileType, String[] title, List<List<String>> 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<Object> insertInfoToBean(List<List<String>> list, Class<?> clazz) throws Exception { List<Object> objs = new ArrayList<Object>(); boolean flag = false; Field[] fields = clazz.getDeclaredFields(); for (int i = 0, len = list.size(); i < len; i++) { Object obj = clazz.newInstance(); for (int j = 0; j < fields.length; j++) { flag = fields[j].isAccessible(); fields[j].setAccessible(true); try { fields[j].set(obj, list.get(i).get(j)); fields[j].setAccessible(flag); } catch (IllegalArgumentException | IllegalAccessException e) { e.printStackTrace(); } } objs.add(obj); } return objs; } private static void writer(String fileTitle, String path, String fileName, String fileType, List<Object> list, String titleRow[]) throws Exception { Workbook wb = null; String excelPath = path + File.separator + fileName + "." + fileType; File file = new File(excelPath); Sheet sheet = null; // 创建工作文档对象 if (!file.exists()) { if (fileType.equals("xls")) { wb = new HSSFWorkbook(); } else if (fileType.equals("xlsx")) { wb = new XSSFWorkbook(); } else { throw new Exception("文件格式不正确"); } // 创建sheet对象 sheet = (Sheet) wb.createSheet("sheet1"); OutputStream outputStream = new FileOutputStream(excelPath); wb.write(outputStream); outputStream.flush(); outputStream.close(); } else { if (fileType.equals("xls")) { wb = new HSSFWorkbook(); } else if (fileType.equals("xlsx")) { wb = new XSSFWorkbook(); } else { throw new Exception("文件格式不正确"); } } // 创建sheet对象 if (sheet == null) { sheet = (Sheet) wb.createSheet("sheet1"); } // 添加表头 Row row = sheet.createRow(0); Cell cell = row.createCell(0); row.setHeight((short) 540); cell.setCellValue(fileTitle); // 创建第一行 CellStyle style = wb.createCellStyle(); // 样式对象 // 设置单元格的背景颜色为淡蓝色 style.setFillForegroundColor(HSSFColor.PALE_BLUE.index); style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);// 垂直 style.setAlignment(CellStyle.ALIGN_CENTER);// 水平 style.setWrapText(true);// 指定当单元格内容显示不下时自动换行 cell.setCellStyle(style); // 样式,居中 Font font = wb.createFont(); font.setBoldweight(Font.BOLDWEIGHT_BOLD); font.setFontName("宋体"); font.setFontHeight((short) 280); style.setFont(font); // 单元格合并 // 四个参数分别是:起始行,起始列,结束行,结束列 sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 7)); sheet.autoSizeColumn(5200); row = sheet.createRow(1); // 创建第二行 for (int i = 0; i < titleRow.length; i++) { cell = row.createCell(i); cell.setCellValue(titleRow[i]); cell.setCellStyle(style); // 样式,居中 sheet.setColumnWidth(i, 20 * 256); } row.setHeight((short) 540); Field[] fields = null; if (!list.isEmpty()) fields = list.get(0).getClass().getDeclaredFields(); // 循环写入行数据 boolean flag = false; for (int i = 0; i < list.size(); i++) { row = (Row) sheet.createRow(i + 2); row.setHeight((short) 500); for (int j = 0; j < fields.length; j++) { flag = fields[j].isAccessible(); fields[j].setAccessible(true); try { row.createCell(j).setCellValue("" + fields[j].get(list.get(i))); } catch (IllegalArgumentException | IllegalAccessException e) { throw new Exception(e.getMessage()); } fields[j].setAccessible(flag); } } // 创建文件流 OutputStream stream = new FileOutputStream(excelPath); // 写入数据 wb.write(stream); // 关闭文件流 stream.close(); } }
相关文章推荐
- PL SQL 怎么比较2个数据库的差异
- SQL怎么将2个数据库联合查询
- 两个数据库的存储过程--视图--表的差异对比结构差异分析
- 两个数据库比较 对比视图存储过程及表结构差异
- 对比两个数据库的表差异——oracle
- 【SHELL】如何对比两个数据库差异?
- SQL Server 对比数据库差异
- 怎么进行2个数据库间的表进行查询连接
- 怎么进行2个数据库间的表进行查询连接
- 比较2个数据库的差异
- 怎么用Beyond Compare对比图片差异
- 两个数据库比较 对比视图存储过程及表结构差异
- 比较2个数据库中表结构差异代码
- 怎么用Beyond Compare对比图片差异
- 两个数据库比较 对比视图存储过程及表结构差异
- (转载) 两个数据库比较 对比视图存储过程及表结构差异
- 比较Oracle 的2个数据库的结构差异,生成更新语句
- 【SHELL】如何对比两个数据库差异?
- 有2个表,结构相似,有一个字段关联,现在怎么把A表的数据添加到B表中,条件是A表不在B表的数据?? 请各位高手多多指点,是oracle的数据库
- 两个数据库比较 对比视图存储过程及表结构差异