1、数据库链接 jdbcTemplate
2、datasource mysqldatasource
3、使用:
配置好2个数据源
配置好2个数据库名
配置好要对比的表名:主键
执行main函数
会打印好对比的结果
项目下载地址: 下载的项目修改数据库后可以直接运行
https://download.csdn.net/download/linhaihai0202/87173288
package com.vince.xq.dataCompare.utils;
import com.mysql.cj.jdbc.MysqlDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class MsqlDefComparisonUtil {
//=================配置部分=================
String database1 = "lhh";
String database2 = "lhh2";
private String url1 = "jdbc:mysql://localhost:3306/lhh";
private String url2 = "jdbc:mysql://localhost:3306/lhh2";
private String user1 = "root";
private String user2 = "root";
private String password1 = "root";
private String password2 = "root";
//那些表需要对比数据;白名单
private List<String> compareDataTables = new ArrayList<>();
{
//表名:主键列明
compareDataTables.add("name:id");
}
//=================配置部分=================
JdbcTemplate jdbcTemplate1;
JdbcTemplate jdbcTemplate2;
public MsqlDefComparisonUtil(){
jdbcTemplate1 = getJdbcTemplate1();
jdbcTemplate2 = getJdbcTemplate2();
}
StringBuilder createTableSB = new StringBuilder();
StringBuilder createColumnSB = new StringBuilder();
StringBuilder updateColumnSB = new StringBuilder();
StringBuilder insertSB = new StringBuilder();
public static void main(String[] args){
MsqlDefComparisonUtil util = new MsqlDefComparisonUtil();
util.compareTable();
util.compareData();
System.out.println("建表语句");
System.out.println(util.createTableSB);
System.out.println("新增列语句");
System.out.println(util.createColumnSB);
System.out.println("修改列语句");
System.out.println(util.updateColumnSB);
System.out.println("插入数据语句");
System.out.println(util.insertSB);
}
private void compareTable(){
//拿到2个库的表清单
List<Map<String, Object>> tables1 =
jdbcTemplate1.queryForList(
String.format("select * from information_schema.tables where table_schema = '%s'",database1));
//拿到2个库的表清单
List<Map<String, Object>> tables2 =
jdbcTemplate2.queryForList(
String.format("select * from information_schema.tables where table_schema = '%s'",database2));
for (Map<String, Object> table1 : tables1) {
String tableName = table1.get("TABLE_NAME").toString();
//对比列
//拿到2个库的表清单
List<Map<String, Object>> columns1 =
jdbcTemplate1.queryForList(
String.format("select * from information_schema.columns where table_schema = '%s' and table_name = '%s' ORDER BY ORDINAL_POSITION",database1,tableName));
long count = tables2.stream().filter(i -> i.get("TABLE_NAME").equals(table1.get("TABLE_NAME"))).count();
if(count == 0){
//todo建表
//CREATE TABLE t1(
//id int not null primary key,
//name char(20)
//);
createTableSB.append("create table `"+tableName+"` (\r\n");
for (Map<String, Object> column1 : columns1) {
createTableSB.append(" ");
createTableSB.append("`"+column1.get("COLUMN_NAME")+"` "+column1.get("COLUMN_TYPE"));
createTableSB.append("NO".equals(column1.get("IS_NULLABLE"))?" NOT NULL":"");
if("auto_increment".equals(column1.get("EXTRA"))) {
createTableSB.append(" AUTO_INCREMENT ");
}
createTableSB.append("PRI".equals(column1.get("COLUMN_KEY"))?" primary key":"");
if(column1.get("COLUMN_DEFAULT") != null) {
createTableSB.append(" DEFAULT '" + column1.get("COLUMN_DEFAULT") + "'");
}
createTableSB.append(" COMMON '"+column1.get("COLUMN_COMMENT")+"',\r\n");
}
createTableSB.append(") ENGINE = "+table1.get("ENGINE")+" CHARACTER SET = utf8mb4;\r\n");
}else{
//拿到2个库的表清单
List<Map<String, Object>> columns2 =
jdbcTemplate2.queryForList(
String.format("select * from information_schema.columns where table_schema = '%s' and table_name = '%s' ORDER BY ORDINAL_POSITION",database2,tableName));
for (Map<String, Object> column1 : columns1) {
List<Map<String, Object>> columnCount = columns2.stream()
.filter(i -> i.get("COLUMN_NAME").equals(column1.get("COLUMN_NAME")))
.collect(Collectors.toList());
if(columnCount == null || columnCount.isEmpty()){
//增加字段
//alter table tb_user add column `create_time` datetime DEFAULT NULL COMMENT '创建时间' ;
createColumnSB.append("ALTER TABLE ");
createColumnSB.append("`"+column1.get("TABLE_NAME")+"`");
createColumnSB.append(" ADD `"+column1.get("COLUMN_NAME")+"` ");
createColumnSB.append(column1.get("COLUMN_TYPE"));
if("NO".equals(column1.get("IS_NULLABLE"))) {
createColumnSB.append(" NOT NULL");
}
if(column1.get("COLUMN_DEFAULT") != null) {
createColumnSB.append(" DEFAULT `" + column1.get("COLUMN_DEFAULT")+"`");
}
createColumnSB.append(" COMMON '"+column1.get("COLUMN_COMMENT")+"'");
createColumnSB.append(";\n");
}else {
Map<String, Object> column2 = columnCount.get(0);
if(!twoMapKeyEquals(column1,column2,
"COLUMN_TYPE","COLUMN_COMMENT","COLUMN_DEFAULT","IS_NULLABLE")){
//修改字段
//ALTER TABLE `user_info` MODIFY COLUMN `name` CHAR(45) COMMENT '姓名';
updateColumnSB.append("ALTER TABLE ");
updateColumnSB.append("`"+column1.get("TABLE_NAME")+"`");
updateColumnSB.append(" MODIFY COLUMN ");
updateColumnSB.append("`"+column1.get("COLUMN_NAME")+"`");
updateColumnSB.append(" "+column1.get("COLUMN_TYPE"));
if("NO".equals(column1.get("IS_NULLABLE"))) {
updateColumnSB.append(" NOT NULL");
}
if(column1.get("COLUMN_DEFAULT") != null) {
updateColumnSB.append(" DEFAULT `" + column1.get("COLUMN_DEFAULT") + "`");
}
if(column1.get("COLUMN_COMMENT") != null) {
updateColumnSB.append(" COMMENT '" + column1.get("COLUMN_COMMENT") + "'");
}
updateColumnSB.append(";\r\n");
}
}
}
}
}
}
/**
* 2个map 的属性都相等
* @param map1
* @param map2
* @param args
* @return
*/
private boolean twoMapKeyEquals(Map<String,Object> map1,Map<String,Object> map2,String ... args){
for (String arg : args) {
Object o1 = map1.get(arg);
Object o2 = map2.get(arg);
if(o1 == null && o2 != null){
return false;
}else if(o1 != null && o2 == null){
return false;
}else if(o1 != null && o2 != null){
if(!o1.equals(o2)){
return false;
}
}
}
return true;
}
private JdbcTemplate getJdbcTemplate1(){
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUser(user1);
dataSource.setPassword(password1);
dataSource.setUrl(url1);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
private JdbcTemplate getJdbcTemplate2(){
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUser(user2);
dataSource.setPassword(password2);
dataSource.setUrl(url2);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
private void compareData(){
for (String item : compareDataTables) {
String table = item.split(":")[0];
String id = item.split(":")[1];
List<Map<String,Object>> maps1 = jdbcTemplate1.queryForList("select * from "+table);
List<Map<String,Object>> maps2 = jdbcTemplate2.queryForList("select * from "+table);
for (Map<String, Object> map1 : maps1) {
long count = maps2.stream().filter(i->i.get(id).equals(map1.get(id))).count();
if(count == 0){
insertSB.append("insert into `"+table+"` (");
int i=0;
for (String s : map1.keySet()) {
if(i == 0){
insertSB.append("`"+s+"`");
}else{
insertSB.append(",`"+s+"`");
}
i++;
}
insertSB.append(")");
insertSB.append("values");
insertSB.append("(");
i=0;
for (String s : map1.keySet()) {
if(i == 0){
insertSB.append("'"+map1.get(s)+"'");
}else{
insertSB.append(",'"+map1.get(s)+"'");
}
i++;
}
insertSB.append(")");
insertSB.append(";\r\n");
}
}
}
}
}