不同数据库数据同步(不同环境的数据库同步 例如测试环境的数据库数据同步到正式环境的库中)

给你一囗甜甜゛ 提交于 2020-10-02 05:42:31
package com.jtl.device.controller;

import cn.hutool.db.handler.BeanListHandler;
import com.jtl.common.config.idgen.SequenceInitForApplication;
import com.jtl.common.config.idgen.SequenceNextUtil;
import com.jtl.common.result.BaseResult;
import com.jtl.device.common.util.SnowflakeIdWorker;
import com.xuanner.seq.sequence.Sequence;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ProjectName: 20200601
 * @Package: com.jtl.device.controller
 * @ClassName: DataBackupController
 * @Author: Administrator
 * @Description: ${description}
 * @Date: 2020/8/19 0019 15:07
 * @Version: 1.0
 */
@Slf4j
@RestController
@RequestMapping("/init/deviceTest")
@Api(description = "同步数据库的接口   注意注意 同步前一定要先备份一下")
public class DataBackupController {

//    public static void main(String[] args) {
////        getId("jtl_sc_device","jtl_device_enabled_dic");
////        try {
////            manage("test", "dev");
////        } catch (SQLException throwables) {
////            throwables.printStackTrace();
////        }
//    }

    @GetMapping("/test")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "start", value = "同步数据前需要先备份  从环境到复制 例如 189的写test   186的写dev   47上的写prd", paramType = "query"),
            @ApiImplicitParam(name = "end", value = "复制到哪个环境  同上  ", paramType = "query"),
            @ApiImplicitParam(name = "table", value = "需要同步的哪个表   例如 jtl_device_type_thresh_dic  ", paramType = "query"),
            @ApiImplicitParam(name = "licence", value = "需要复制的那个协议号 例如 0202", paramType = "query"),
            @ApiImplicitParam(name = "param", value = "哪个参数和协议号完整才能组成一条数据 一般都是code  例如 threshold_dic_code", paramType = "query"),
    })
    public BaseResult test(@RequestParam(value = "start",required = true) String start, @RequestParam(value = "end",required = true) String end,
                           @RequestParam("table") String table,
                           @RequestParam("licence") String licence,
                           @RequestParam("param") String param) {
//    public BaseResult test(@RequestParam("start") String start, @RequestParam("end") String end) {
        try {
//            findNeedList(start, end, "jtl_sc_device", "jtl_device_type_thresh_dic", "0202", "threshold_dic_code");

            findNeedList(start, end, "jtl_sc_device", table, licence, param);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new BaseResult();
    }


    private static Long getId(String database, String table) {
        String name = database + "." + table;
        SequenceInitForApplication sa = new SequenceInitForApplication();
        Sequence sequence = sa.getSeqBySt(name);
        if (sequence == null) {
            System.out.println("sequence 不匹配, st={}" + name);
            return null;
        }
        return sequence.nextValue();
    }


    private static Connection getMysqlconn(String type, String database) {
        try {
            String url = "jdbc:mysql://192.168.0.61:3306/";
            String password = "123456";
            switch (type) {
                case "localhost":
                    url = "jdbc:mysql://localhost:3306/";
                    password = "root";
                    break;
                case "dev":
                    url = "jdbc:mysql://192.168.0.2:3306/";
                    break;
                case "test":
                    url = "jdbc:mysql://192.168.0.1:3306/";
                    break;
                case "prd":
                    url = "jdbc:mysql://192.168.0.3:3306/";
                    break;
            }
            url = url + database + "?relaxAutoCommit=true&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&useSSL=false&serverTimezone=Hongkong";

            Class.forName("com.mysql.cj.jdbc.Driver");
            return DriverManager.getConnection(url, "root", password);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void manage(String begin, String end) throws SQLException {
//        findNeedList(begin, end, "jtl_sc_device", "jtl_device_application_dic","apply_name", null);
//        findNeedList(begin, end, "jtl_sc_device","jtl_device_application_model_dic" ,"production_name",null);

//        findNeedList(begin, end, "jtl_sc_device", "jtl_device_enable_desc_dic", "licence", "enabled_code");
//        findNeedList(begin, end, "jtl_sc_device","jtl_device_type_alarm_dic" ,"licence","alarm_dic_code");
//        findNeedList(begin, end, "jtl_sc_device","jtl_device_type_data_dic" ,"licence","data_dic_code");
//        findNeedList(begin, end, "jtl_sc_device","jtl_device_type_order_dic" ,"licence","order_dic_code");
//        findNeedList(begin, end, "jtl_sc_device","jtl_device_type_state_dic" ,"licence","state_dic_code");
//        findNeedList(begin, end, "jtl_sc_device","jtl_device_type_thresh_dic" ,"licence","threshold_dic_code");
//

//        findNeedList(begin, end, "jtl_sc_device","jtl_device_system_dic" ,"alarm_dic_code");
//        findNeedList(begin, end, "jtl_sc_pub", "jtl_device_dic","type", "data_dic_code");

    }

    /**
     * 查询需要更新的list
     *
     * @param begin
     * @param end
     * @param database
     * @param table
     * @param type
     * @param code
     * @throws SQLException
     */
    public void findNeedList(String begin, String end, String database, String table, String type, String code) throws SQLException {
        Connection beginConn = getMysqlconn(begin, database);
        if (beginConn == null) {
            System.out.println("beginConn is null ");
            return;
        }
        Statement beginstmt = beginConn.createStatement();

        Connection endConn2 = getMysqlconn(end, database);
        if (endConn2 == null) {
            System.out.println("beginConn is null ");
            return;
        }
        Statement endStatement = endConn2.createStatement();

        String sql = "select * from " + table + " where del_flag = 0 and licence=" + type;


        ResultSet begins = beginstmt.executeQuery(sql);
        ResultSet endResult = endStatement.executeQuery(sql);

        List<Map<String, Object>> newList = new ArrayList<>();
        if (StringUtils.isNotEmpty(type) && StringUtils.isNotEmpty(code)) {
            newList = getNewList(begins, endResult, type, code);
        }
//        else if (StringUtils.isNotEmpty(type)) {
//            newList = getPubList(begins, endResult, type);
//        }

        close(endConn2, endStatement, endResult);
        close(beginConn, beginstmt, begins);

        if (CollectionUtils.isEmpty(newList)) {
            //没有要更新的数据
            System.out.println(table + " 没有要更新的数据");
            return;
        }


        insertTable(end, database, table, newList);

    }

    /**
     * 插入list
     *
     * @param end
     * @param database
     * @param table
     * @param newList
     * @throws SQLException
     */
    public static void insertTable(String end, String database, String table, List<Map<String, Object>> newList) throws SQLException {
        int size = newList.get(0).size();
        //拼接insert into 语句
        StringBuffer sbf = new StringBuffer();
        sbf.append("insert into " + table + " values (");
        String link = "";
        for (int i = 0; i < size; i++) {
            sbf.append(link).append("?");
            link = ",";
        }
        sbf.append(")");
        sbf.append(" on duplicate key update ");
        String link2 = "";
        for (Map.Entry<String, Object> entry : newList.get(0).entrySet()) {
            if (!"id".equals(entry.getKey())) {
                sbf.append(link2).append(entry.getKey() + " = values(" + entry.getKey() + ")");
                link2 = ",";
            }
        }

        System.out.println(sbf.toString());

        //MySQL数据库
        Connection endConn = getMysqlconn(end, database);
        PreparedStatement endstmt = endConn.prepareStatement(sbf.toString());


        //取出结果集并向MySQL数据库插入数据 ( 使用批处理 )
        //完成条数
        int count = 0;
        int num = 0;
        //取消事务(不写入日志)
        endConn.setAutoCommit(false);
        long start = System.currentTimeMillis();

        for (Map<String, Object> map : newList) {
            ++count;
            int i = 1;
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                endstmt.setObject(i, entry.getValue());
                i++;
            }
            //将预先语句存储起来,这里还没有向数据库插入
            endstmt.addBatch();
            //count 到达 20000条时 向数据库提交
            if (count % 50 == 0) {
                ++num;
                endstmt.executeBatch();
                System.out.println("" + num + "次提交");
            }
        }

        //防止有数据未提交
        int[] i = endstmt.executeBatch();
        //提交
        endConn.commit();
        System.out.println(table + " 完成 " + count + " 条数据,耗时:" + (System.currentTimeMillis() - start) / 1000.0 + "s");
        //恢复事务
        // endConn.setAutoCommit(true);

        //关闭资源
        close(endConn, endstmt, null);
    }

    public static void close(Connection conn, Statement stmt, ResultSet rs) {

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取表中所有更改或者不存在的数据list
     *
     * @param begins
     * @param endResult
     * @return
     * @throws SQLException
     */
    private List<Map<String, Object>> getNewList(ResultSet begins, ResultSet endResult, String licence, String code) throws SQLException {

        BeanListHandler<Object> bh = new BeanListHandler<Object>(Object.class);
        //beginsResultSet得到的从返回集合
        List<Object> beginList = bh.handle(begins);
        List<Object> endList = bh.handle(endResult);
        List<Map<String, Object>> newList = new ArrayList<>();
        List<Object> licenceFilterList = endList.stream().map(object -> getObjectToMap(object).get(licence)).collect(Collectors.toList());
        for (Object p1 : beginList) {
            Boolean statue = true;
            Map<String, Object> map = new HashMap<>();
            Map<String, Object> map1 = getObjectToMap(p1);

            String licence1 = map1.get("licence") == null ? "" : map1.get("licence").toString();
            String code1 = map1.get(code) == null ? "" : map1.get(code).toString();
            if (StringUtils.isEmpty(licence1) && StringUtils.isEmpty(code1)) {
                statue = false;
            }else {
                for (Object p2 : endList) {
                    Map<String, Object> map2 = getObjectToMap(p2);
                    String licence2 = map2.get("licence") == null ? "" : map2.get("licence").toString();
                    String code2 = map2.get(code) == null ? "" : map2.get(code).toString();
                    if (StringUtils.isEmpty(licence2) && StringUtils.isEmpty(code2)) {
                        statue = false;
                    } else if (licence1.equals(licence2) && code1.equals(code2)) {
                        log.info("相同的协议号和相同的code 不添加");
                        statue = false;
                        break;
                    }

                }
            }


            if (statue) {
                //插入主键
                // id获取从雪花算法 迁移到 sequence获取

                Long id = SequenceNextUtil.next("jtl_sc_device.jtl_device_enable_desc_dic");
//                Long id = SnowflakeIdWorker.generateId();
                map = map1;
                map.put("id", id);
            }
            if (!map.isEmpty()) {
                newList.add(map);
            }
        }
        return newList;
    }

    /**
     * 获取表中所有更改或者不存在的数据list
     *
     * @param begins
     * @param endResult
     * @return
     * @throws SQLException
     */
    private static List<Map<String, Object>> getPubList(ResultSet begins, ResultSet endResult, String code) throws SQLException {

        BeanListHandler<Object> bh = new BeanListHandler<Object>(Object.class);
        //beginsResultSet得到的从返回集合
        List<Object> beginList = bh.handle(begins);
        List<Object> endList = bh.handle(endResult);
        List<Map<String, Object>> newList = new ArrayList<>();
        List<Object> codeFilterList = endList.stream().map(object -> getObjectToMap(object).get(code)).collect(Collectors.toList());
        for (Object p1 : beginList) {
            Boolean statue = true;
            Map<String, Object> map = new HashMap<>();
            Map<String, Object> map1 = getObjectToMap(p1);

            String code1 = map1.get(code) == null ? "" : map1.get(code).toString();
            if (StringUtils.isEmpty(code1)) {
                statue = false;
            } else if (codeFilterList.contains(code1)) {
                for (Object p2 : endList) {
                    Map<String, Object> map2 = getObjectToMap(p2);
                    String code2 = map2.get(code) == null ? "" : map2.get(code).toString();
                    if (StringUtils.isEmpty(code2)) {
                        statue = false;
                    } else if (code1.equals(code2)) {
                        //通过输入字段确定是否更新
                        Boolean compare = compare(map1, map2);
                        System.out.println("compare:" + compare);
                        if (!compare) {
                            System.out.println(map1);
                            System.out.println(map2);
                        }
                        if (compare) {
                            statue = false;
                            break;
                        }
                        map = map1;
                        map.put("id", map2.get("id"));
                        statue = false;
                        break;
                    }

                }
            }

            if (statue) {
                //插入主键
                Long recordId = SequenceNextUtil.next("jtl_sc_record.jtl_device_record");
//                Double random = Math.floor(Math.random() * (999999 - 100000 + 1) + 100000);
//                String id = String.valueOf(random.intValue());
                map = map1;
                map.put("id", recordId);
            }
            if (!map.isEmpty()) {
                newList.add(map);
            }
        }
        return newList;
    }


    //ObjectMap
    public static Map<String, Object> getObjectToMap(Object obj) {
        Map<String, Object> map = (HashMap<String, Object>) obj;
        return map;
    }

    private static Boolean compare(Map<String, Object> map1, Map<String, Object> map2) {
        for (String dickey : map1.keySet()) {
            if (!"licence".equals(dickey) && !"alarm_dic_code".equals(dickey)) {
                String dicvalue1 = map1.get(dickey) == null ? "" : map1.get(dickey).toString();
                String dicvalue2 = map2.get(dickey) == null ? "" : map2.get(dickey).toString();
                if (!dicvalue1.equals(dicvalue2)) {
                    return false;
                }
            }
        }
        return true;
    }


}

 

因为业务的需要 每添加一个设备就需要配置很多的参数   开发环境配置好了 又要配置测试环境  测试环境配置好了 又要配置正式环境 ,一天天的都是配置数据了    为了方便    做了一个库库同步  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!