• MYSQL 数据库对比 工具类


    1、数据库链接 jdbcTemplate

    2、datasource mysqldatasource

    3、使用:

         配置好2个数据源

         配置好2个数据库名

         配置好要对比的表名:主键

          执行main函数

          会打印好对比的结果

    项目下载地址: 下载的项目修改数据库后可以直接运行

    https://download.csdn.net/download/linhaihai0202/87173288

    1. package com.vince.xq.dataCompare.utils;
    2. import com.mysql.cj.jdbc.MysqlDataSource;
    3. import org.springframework.jdbc.core.JdbcTemplate;
    4. import java.util.ArrayList;
    5. import java.util.List;
    6. import java.util.Map;
    7. import java.util.stream.Collectors;
    8. public class MsqlDefComparisonUtil {
    9. //=================配置部分=================
    10. String database1 = "lhh";
    11. String database2 = "lhh2";
    12. private String url1 = "jdbc:mysql://localhost:3306/lhh";
    13. private String url2 = "jdbc:mysql://localhost:3306/lhh2";
    14. private String user1 = "root";
    15. private String user2 = "root";
    16. private String password1 = "root";
    17. private String password2 = "root";
    18. //那些表需要对比数据;白名单
    19. private List<String> compareDataTables = new ArrayList<>();
    20. {
    21. //表名:主键列明
    22. compareDataTables.add("name:id");
    23. }
    24. //=================配置部分=================
    25. JdbcTemplate jdbcTemplate1;
    26. JdbcTemplate jdbcTemplate2;
    27. public MsqlDefComparisonUtil(){
    28. jdbcTemplate1 = getJdbcTemplate1();
    29. jdbcTemplate2 = getJdbcTemplate2();
    30. }
    31. StringBuilder createTableSB = new StringBuilder();
    32. StringBuilder createColumnSB = new StringBuilder();
    33. StringBuilder updateColumnSB = new StringBuilder();
    34. StringBuilder insertSB = new StringBuilder();
    35. public static void main(String[] args){
    36. MsqlDefComparisonUtil util = new MsqlDefComparisonUtil();
    37. util.compareTable();
    38. util.compareData();
    39. System.out.println("建表语句");
    40. System.out.println(util.createTableSB);
    41. System.out.println("新增列语句");
    42. System.out.println(util.createColumnSB);
    43. System.out.println("修改列语句");
    44. System.out.println(util.updateColumnSB);
    45. System.out.println("插入数据语句");
    46. System.out.println(util.insertSB);
    47. }
    48. private void compareTable(){
    49. //拿到2个库的表清单
    50. List<Map<String, Object>> tables1 =
    51. jdbcTemplate1.queryForList(
    52. String.format("select * from information_schema.tables where table_schema = '%s'",database1));
    53. //拿到2个库的表清单
    54. List<Map<String, Object>> tables2 =
    55. jdbcTemplate2.queryForList(
    56. String.format("select * from information_schema.tables where table_schema = '%s'",database2));
    57. for (Map<String, Object> table1 : tables1) {
    58. String tableName = table1.get("TABLE_NAME").toString();
    59. //对比列
    60. //拿到2个库的表清单
    61. List<Map<String, Object>> columns1 =
    62. jdbcTemplate1.queryForList(
    63. String.format("select * from information_schema.columns where table_schema = '%s' and table_name = '%s' ORDER BY ORDINAL_POSITION",database1,tableName));
    64. long count = tables2.stream().filter(i -> i.get("TABLE_NAME").equals(table1.get("TABLE_NAME"))).count();
    65. if(count == 0){
    66. //todo建表
    67. //CREATE TABLE t1(
    68. //id int not null primary key,
    69. //name char(20)
    70. //);
    71. createTableSB.append("create table `"+tableName+"` (\r\n");
    72. for (Map<String, Object> column1 : columns1) {
    73. createTableSB.append(" ");
    74. createTableSB.append("`"+column1.get("COLUMN_NAME")+"` "+column1.get("COLUMN_TYPE"));
    75. createTableSB.append("NO".equals(column1.get("IS_NULLABLE"))?" NOT NULL":"");
    76. if("auto_increment".equals(column1.get("EXTRA"))) {
    77. createTableSB.append(" AUTO_INCREMENT ");
    78. }
    79. createTableSB.append("PRI".equals(column1.get("COLUMN_KEY"))?" primary key":"");
    80. if(column1.get("COLUMN_DEFAULT") != null) {
    81. createTableSB.append(" DEFAULT '" + column1.get("COLUMN_DEFAULT") + "'");
    82. }
    83. createTableSB.append(" COMMON '"+column1.get("COLUMN_COMMENT")+"',\r\n");
    84. }
    85. createTableSB.append(") ENGINE = "+table1.get("ENGINE")+" CHARACTER SET = utf8mb4;\r\n");
    86. }else{
    87. //拿到2个库的表清单
    88. List<Map<String, Object>> columns2 =
    89. jdbcTemplate2.queryForList(
    90. String.format("select * from information_schema.columns where table_schema = '%s' and table_name = '%s' ORDER BY ORDINAL_POSITION",database2,tableName));
    91. for (Map<String, Object> column1 : columns1) {
    92. List<Map<String, Object>> columnCount = columns2.stream()
    93. .filter(i -> i.get("COLUMN_NAME").equals(column1.get("COLUMN_NAME")))
    94. .collect(Collectors.toList());
    95. if(columnCount == null || columnCount.isEmpty()){
    96. //增加字段
    97. //alter table tb_user add column `create_time` datetime DEFAULT NULL COMMENT '创建时间' ;
    98. createColumnSB.append("ALTER TABLE ");
    99. createColumnSB.append("`"+column1.get("TABLE_NAME")+"`");
    100. createColumnSB.append(" ADD `"+column1.get("COLUMN_NAME")+"` ");
    101. createColumnSB.append(column1.get("COLUMN_TYPE"));
    102. if("NO".equals(column1.get("IS_NULLABLE"))) {
    103. createColumnSB.append(" NOT NULL");
    104. }
    105. if(column1.get("COLUMN_DEFAULT") != null) {
    106. createColumnSB.append(" DEFAULT `" + column1.get("COLUMN_DEFAULT")+"`");
    107. }
    108. createColumnSB.append(" COMMON '"+column1.get("COLUMN_COMMENT")+"'");
    109. createColumnSB.append(";\n");
    110. }else {
    111. Map<String, Object> column2 = columnCount.get(0);
    112. if(!twoMapKeyEquals(column1,column2,
    113. "COLUMN_TYPE","COLUMN_COMMENT","COLUMN_DEFAULT","IS_NULLABLE")){
    114. //修改字段
    115. //ALTER TABLE `user_info` MODIFY COLUMN `name` CHAR(45) COMMENT '姓名';
    116. updateColumnSB.append("ALTER TABLE ");
    117. updateColumnSB.append("`"+column1.get("TABLE_NAME")+"`");
    118. updateColumnSB.append(" MODIFY COLUMN ");
    119. updateColumnSB.append("`"+column1.get("COLUMN_NAME")+"`");
    120. updateColumnSB.append(" "+column1.get("COLUMN_TYPE"));
    121. if("NO".equals(column1.get("IS_NULLABLE"))) {
    122. updateColumnSB.append(" NOT NULL");
    123. }
    124. if(column1.get("COLUMN_DEFAULT") != null) {
    125. updateColumnSB.append(" DEFAULT `" + column1.get("COLUMN_DEFAULT") + "`");
    126. }
    127. if(column1.get("COLUMN_COMMENT") != null) {
    128. updateColumnSB.append(" COMMENT '" + column1.get("COLUMN_COMMENT") + "'");
    129. }
    130. updateColumnSB.append(";\r\n");
    131. }
    132. }
    133. }
    134. }
    135. }
    136. }
    137. /**
    138. * 2个map 的属性都相等
    139. * @param map1
    140. * @param map2
    141. * @param args
    142. * @return
    143. */
    144. private boolean twoMapKeyEquals(Map<String,Object> map1,Map<String,Object> map2,String ... args){
    145. for (String arg : args) {
    146. Object o1 = map1.get(arg);
    147. Object o2 = map2.get(arg);
    148. if(o1 == null && o2 != null){
    149. return false;
    150. }else if(o1 != null && o2 == null){
    151. return false;
    152. }else if(o1 != null && o2 != null){
    153. if(!o1.equals(o2)){
    154. return false;
    155. }
    156. }
    157. }
    158. return true;
    159. }
    160. private JdbcTemplate getJdbcTemplate1(){
    161. MysqlDataSource dataSource = new MysqlDataSource();
    162. dataSource.setUser(user1);
    163. dataSource.setPassword(password1);
    164. dataSource.setUrl(url1);
    165. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    166. return jdbcTemplate;
    167. }
    168. private JdbcTemplate getJdbcTemplate2(){
    169. MysqlDataSource dataSource = new MysqlDataSource();
    170. dataSource.setUser(user2);
    171. dataSource.setPassword(password2);
    172. dataSource.setUrl(url2);
    173. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    174. return jdbcTemplate;
    175. }
    176. private void compareData(){
    177. for (String item : compareDataTables) {
    178. String table = item.split(":")[0];
    179. String id = item.split(":")[1];
    180. List<Map<String,Object>> maps1 = jdbcTemplate1.queryForList("select * from "+table);
    181. List<Map<String,Object>> maps2 = jdbcTemplate2.queryForList("select * from "+table);
    182. for (Map<String, Object> map1 : maps1) {
    183. long count = maps2.stream().filter(i->i.get(id).equals(map1.get(id))).count();
    184. if(count == 0){
    185. insertSB.append("insert into `"+table+"` (");
    186. int i=0;
    187. for (String s : map1.keySet()) {
    188. if(i == 0){
    189. insertSB.append("`"+s+"`");
    190. }else{
    191. insertSB.append(",`"+s+"`");
    192. }
    193. i++;
    194. }
    195. insertSB.append(")");
    196. insertSB.append("values");
    197. insertSB.append("(");
    198. i=0;
    199. for (String s : map1.keySet()) {
    200. if(i == 0){
    201. insertSB.append("'"+map1.get(s)+"'");
    202. }else{
    203. insertSB.append(",'"+map1.get(s)+"'");
    204. }
    205. i++;
    206. }
    207. insertSB.append(")");
    208. insertSB.append(";\r\n");
    209. }
    210. }
    211. }
    212. }
    213. }

  • 相关阅读:
    基于Java实现的离散数学测试实验
    redis6.2(二)Redis的新数据类型、使用java语言操作Redis
    推荐系统工业界顶会论文总结——WSDM 2021
    操作系统——网络编程——socket——TCP/UDP
    TiCDC 重要监控指标详解
    JAVASE---认识异常
    springboot:时间格式化的5种方法(解决后端传给前端的时间格式转换问题)推荐使用第4和第5种!
    基于截止至 2023 年 5 月 30 日,在 App Store 上进行交易的设备数据统计,iOS/iPadOS 各版本更新情况
    python-pytorch 实现seq2seq+luong general concat attention笔记1.0.10
    第二部分—C语言提高篇_12. 动/精态库的封装和使用
  • 原文地址:https://blog.csdn.net/linhaihai0202/article/details/128057822