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); //begins是ResultSet得到的从返回集合 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); //begins是ResultSet得到的从返回集合 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; } //Object转Map 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; } }
因为业务的需要 每添加一个设备就需要配置很多的参数 开发环境配置好了 又要配置测试环境 测试环境配置好了 又要配置正式环境 ,一天天的都是配置数据了 为了方便 做了一个库库同步
来源:oschina
链接:https://my.oschina.net/liudandan/blog/4517171