package com.njcn.influx.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.njcn.influx.bo.param.TableEnum;
import com.njcn.influx.bo.po.JobDetailHoursInfluxDB;
import com.njcn.influx.bo.po.JobDetailInfluxDB;
import com.njcn.influx.bo.po.JobHistoryLogInfluxdb;
import com.njcn.influx.config.IdMappingCache;
import com.njcn.influx.config.RedisUtil;
import com.njcn.influx.service.JobDetailHoursInfluxDBService;
import com.njcn.influx.service.JobDetailInfluxDBService;
import com.njcn.influx.service.JobHistoryLogInfluxdbService;
import com.njcn.influx.service.OracleToInfluxDBService;
import com.njcn.oracle.bo.lineTimeDto;
import com.njcn.oracle.bo.param.DataAsynParam;
import com.njcn.oracle.bo.param.MigrationParam;
import com.njcn.oracle.mapper.LineTimeMapper;
import com.njcn.oracle.mybatis.service.IReplenishMybatisService;
import com.njcn.oracle.util.LocalDateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Description:
 * Date: 2024/1/16  14:49【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */

@Service
@RequiredArgsConstructor
@Slf4j
public class OracleToInfluxDBServiceImpl implements OracleToInfluxDBService {


    private final static String PACKAGE_PREFIX = "com.njcn.oracle.service.impl.";
    private final static String PACKAGE_SUFFIX = "ServiceImpl";

    private final JobDetailInfluxDBService jobDetailInfluxDBService;

    private final InfluxDBBaseServiceImpl influxDBBaseService;

    private final IdMappingCache idMappingCache;

    private final JobHistoryLogInfluxdbService jobHistoryLogInfluxdbService;

    private final JobDetailHoursInfluxDBService jobDetailHoursInfluxDBService;

    private final LineTimeMapper lineTimeMapper;
    private final RedisUtil redisUtil;
    @Value("${business.slice:2}")
    private int slice;

    @Override
    @Async
    public void dataBacthSysc(DataAsynParam dataAsynParam) {
        Map<String, String> LineIdMapping = (Map<String, String>) redisUtil.getObjectByKey("LineIdMapping");
        Runtime runtime = Runtime.getRuntime();
        System.out.println("开始执行前总堆内存为：" + runtime.totalMemory() / (1024 * 1024) + " MB");
        System.out.println("开始执行前已用堆内存为：" + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + " MB");
        System.out.println("开始执行前空闲堆内存为：" + runtime.freeMemory() / (1024 * 1024) + " MB");
        //目前且作为2片，后续将该属性提取到配置文件中
        List<String> tableNames = dataAsynParam.getTableNames();
        //嵌套循环，先循环指标，再循环日期
        tableNames.stream().forEach(tableName -> {
            IReplenishMybatisService executor;
            try {
                executor = (IReplenishMybatisService) SpringUtil.getBean(Class.forName(PACKAGE_PREFIX + tableName + PACKAGE_SUFFIX));
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            List<LocalDate> dateList = LocalDateUtil.getDateList(dataAsynParam.getStartTime(), dataAsynParam.getEndTime());
            for (LocalDate date : dateList) {


                //添加记录批处理日志，执行为批处理且最后一张表执行完记录
                if(dataAsynParam.getExcuteType()==2&&Objects.equals(tableName, TableEnum.DATAHARMPOWERS.getCode())){
                    JobHistoryLogInfluxdb jobHistoryLogInfluxdbLog = new JobHistoryLogInfluxdb(date,LocalDateTime.now());
                    jobHistoryLogInfluxdbService.save(jobHistoryLogInfluxdbLog);
                }

                //日志记录
                JobDetailInfluxDB jobDetailInfluxDB = jobDetailInfluxDBService.select(tableName, date);
                if (Objects.nonNull(jobDetailInfluxDB) && (jobDetailInfluxDB.getState() == 1 || jobDetailInfluxDB.getState() == 0)) {
                    //如果该指标当前天已执行或正在执行，直接跳出循环
                    break;
                }
                if (Objects.isNull(jobDetailInfluxDB)) {
                    jobDetailInfluxDB = new JobDetailInfluxDB(tableName, date, 0, 0, LocalDateTime.now());
                    jobDetailInfluxDBService.save(jobDetailInfluxDB);
                }
                //程序监听
                StopWatch stopWatch = new StopWatch();
                stopWatch.start();
                //分片下，每段时间的小时数
                int sliceHour = 24 / slice;
                for (int i = 0; i < slice; i++) {
                    String dateStr = LocalDateTimeUtil.format(date, DatePattern.NORM_DATE_PATTERN);
                    LocalDateTime startTime = LocalDateTimeUtil.parse(dateStr + StrPool.C_SPACE + (sliceHour * i < 10 ? "0" + sliceHour * i : sliceHour * i) + ":00:00", DatePattern.NORM_DATETIME_PATTERN);
                    LocalDateTime endTime = LocalDateTimeUtil.parse(dateStr + StrPool.C_SPACE + (sliceHour * (i + 1) - 1 < 10 ? "0" + (sliceHour * (i + 1) - 1) : sliceHour * (i + 1) - 1) + ":59:59", DatePattern.NORM_DATETIME_PATTERN);
                    //查询该时区的数据，并准备入库
                    MigrationParam migration = new MigrationParam();
                    migration.setStartTime(startTime);
                    migration.setEndTime(endTime);
                    List list = executor.queryData(migration);
                    //反射獲取linid的值并把linid的值替换成mysql对应的linid，并记录未匹配的lineid
                    Iterator iterator = list.iterator();
                    while (iterator.hasNext()) {
                        try{
                            Object obj = iterator.next();
                            //获取
                            Field id = obj.getClass().getDeclaredField("lineid");
                            id.setAccessible(true); //暴力访问id
                            String id1 = id.get(obj).toString();
                            if (!LineIdMapping.containsKey(id1)){
                                log.info(tableName+"表---Oralcet数据同步到InfluxDB未找mysql中到lineid匹配的lineid"+id1);
                                iterator.remove();
                            }else {
                                id.set(obj, LineIdMapping.get(id1));
                            }
                        }catch (Exception e){
                            e.printStackTrace();
                        }

                    }

                    //采用弱引用接受，后续手动调用gc后，会清空该对象
                    WeakReference<List> weakReferenceData = new WeakReference<>(list);
                    int size = 0;
                    if (CollectionUtil.isNotEmpty(weakReferenceData.get())) {
                        size = weakReferenceData.get().size();
                    }
                    System.out.println(tableName + "查到" + size + "条数据后总堆内存为：" + runtime.totalMemory() / (1024 * 1024) + " MB");
                    System.out.println(tableName + "查到" + size + "条数据后已用堆内存为：" + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + " MB");
                    System.out.println(tableName + "查到" + size + "条数据后空闲堆内存为：" + runtime.freeMemory() / (1024 * 1024) + " MB");
                    try {
                        if (CollectionUtil.isNotEmpty(weakReferenceData.get())) {
                            //执行目标库的数据处理
                            Class<?> clazz;
                            Class<?> clazz2;
                            //获取Table表对应的influxdb对应的表的实体类调用oralceToInfluxDB方法及oralceToInfluxDB的入参clazz2
                            try {
                                clazz = Class.forName("com.njcn.influx.bo.po.InfluxDB" + tableName);
                                clazz2 = Class.forName("com.njcn.oracle.bo.po." + tableName);
                            } catch (ClassNotFoundException e) {
                                throw new RuntimeException(e);
                            }
                            Method method;
                            try {
                                method = clazz.getDeclaredMethod("oralceToInfluxDB", clazz2);
                            } catch (NoSuchMethodException e) {
                                throw new RuntimeException(e);
                            }
                            method.setAccessible(true);
                            Method finalMethod = method;
                            List list1 = (List) weakReferenceData.get().stream().flatMap(po -> {
                                try {
                                    Object invoke = finalMethod.invoke(null, po);
                                    Object invoke1 = invoke;
                                    //返回oracle转influx，flicker等表是1-1，还有1-4，这是判断返回是否是集合如何是集合继续扁平化
                                    return invoke1 instanceof List ? ((List<?>) invoke1).stream() : Stream.of(invoke1);
                                } catch (Exception e) {
                                    throw new RuntimeException(e);
                                }
                            }).collect(Collectors.toList());
                            //插入influxdb
                            influxDBBaseService.insertBatchBySlice(tableName, list1, 10000);
//                            size = list1.size();
                            //最后一片时修改状态
                        }
                        //手动执行GC
                        System.gc();
                        if (i == 0) {
                            jobDetailInfluxDB.setRowCount(0);
                        }
                        jobDetailInfluxDB.setRowCount(jobDetailInfluxDB.getRowCount() + size*TableEnum.getMultipleByCode(tableName));
                        if (i + 1 == slice) {
                            stopWatch.stop();
                            jobDetailInfluxDB.setState(1);
                            jobDetailInfluxDB.setDuration(stopWatch.getTotalTimeSeconds());
                        }
                        jobDetailInfluxDB.setUpdateTime(LocalDateTime.now());
                        jobDetailInfluxDBService.updateByMultiId(jobDetailInfluxDB);
                    } catch (Exception exception) {
                        exception.printStackTrace();
                        jobDetailInfluxDB.setState(2);
                        jobDetailInfluxDB.setUpdateTime(LocalDateTime.now());
                        jobDetailInfluxDBService.updateByMultiId(jobDetailInfluxDB);
                    }
                    System.out.println("执行后总堆内存为：" + runtime.totalMemory() / (1024 * 1024) + " MB");
                    System.out.println("执行后已用堆内存为：" + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + " MB");
                    System.out.println("执行后空闲堆内存为：" + runtime.freeMemory() / (1024 * 1024) + " MB");
                }
            }
        });
    }

    //冀北现场存在数据更新时间不在1小时内，会丢失数据的情况，这边根据装置最新时间往前推1个小时查询数据
    @Override
    public void hourseDataBacthSysc(DataAsynParam dataAsynParam) {
        Map<String, String> LineIdMapping = (Map<String, String>) redisUtil.getObjectByKey("LineIdMapping");
        List<Integer> oracleLineIdList = LineIdMapping.keySet().stream().map(Integer::parseInt).collect(Collectors.toList());
        Map<String, String> DevIdMapping = (Map<String, String>) redisUtil.getObjectByKey("DevIdMapping");

        Runtime runtime = Runtime.getRuntime();
        System.out.println("开始执行前总堆内存为：" + runtime.totalMemory() / (1024 * 1024) + " MB");
        System.out.println("开始执行前已用堆内存为：" + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + " MB");
        System.out.println("开始执行前空闲堆内存为：" + runtime.freeMemory() / (1024 * 1024) + " MB");
        //目前且作为2片，后续将该属性提取到配置文件中
        List<String> tableNames = dataAsynParam.getTableNames();
        //嵌套循环，先循环指标，再循环日期
        tableNames.stream().forEach(tableName -> {
            IReplenishMybatisService executor;
            try {
                executor = (IReplenishMybatisService) SpringUtil.getBean(Class.forName(PACKAGE_PREFIX + tableName + PACKAGE_SUFFIX));
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            //日志记录
//            JobDetailHoursInfluxDB jobDetailInfluxDBHours = jobDetailHoursInfluxDBService.lambdaQuery().eq(JobDetailHoursInfluxDB::getTableName, tableName)
//                    .eq(JobDetailHoursInfluxDB::getExcuteDate, dataAsynParam.getStartDateTime())
//                    .one();
//            if (Objects.nonNull(jobDetailInfluxDBHours) && (jobDetailInfluxDBHours.getState() == 1 || jobDetailInfluxDBHours.getState() == 0|| jobDetailInfluxDBHours.getState() == 2)) {
//                //如果该指标当前时间段已执行或正在执行，直接跳出循环
//                return;
//            }
//            if (Objects.isNull(jobDetailInfluxDBHours)) {
//                jobDetailInfluxDBHours = new JobDetailHoursInfluxDB(tableName, dataAsynParam.getStartDateTime(), 0, 0, LocalDateTime.now());
//                jobDetailHoursInfluxDBService.save(jobDetailInfluxDBHours);
//            }
            //程序监听
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            List list = new ArrayList(Collections.emptyList());
            if("ComInfoRmation".equals(tableName)){
                MigrationParam migration = new MigrationParam();
                migration.setStartTime(dataAsynParam.getStartDateTime());
                migration.setEndTime(dataAsynParam.getEndDateTime());
                migration.setLineIds(oracleLineIdList);
                System.out.println("执行扫描起始时间------------------------------------"+dataAsynParam.getStartDateTime().minusHours(2).format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
                System.out.println("执行扫描结束时间------------------------------------"+dataAsynParam.getEndDateTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
                list.addAll(executor.queryData(migration));
                System.out.println("查询到的数据++++++++++++++"+list.size());
                //反射获取linid的值并把linid的值替换成mysql对应的devid，并记录未匹配的devid
                Iterator iterator = list.iterator();
                while (iterator.hasNext()) {
                    try{
                        Object obj = iterator.next();
                        //获取
                        Field id = obj.getClass().getDeclaredField("lineIndex");
                        id.setAccessible(true); //暴力访问id
                        Object o = id.get(obj);
                        if(ObjectUtil.isNotNull(o)){
                            int index = Integer.parseInt(o.toString())/10;
                            if (!DevIdMapping.containsKey(index+"")){
                                log.info(tableName+"表---Oralcet数据同步到InfluxDB未找mysql中到devid匹配的devid"+index);
                                iterator.remove();
                            }else {
                                id.set(obj, DevIdMapping.get(index+""));
                            }
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }else{
                MigrationParam migration = new MigrationParam();
                migration.setStartTime(dataAsynParam.getStartDateTime());
                migration.setEndTime(dataAsynParam.getEndDateTime());
                migration.setLineIds(oracleLineIdList);
                System.out.println("执行扫描起始时间------------------------------------"+dataAsynParam.getStartDateTime().minusHours(2).format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
                System.out.println("执行扫描结束时间------------------------------------"+dataAsynParam.getEndDateTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
                list.addAll(executor.queryData(migration));
                //获取监测点最新的数据时间，单监测点查询数据
//                List<lineTimeDto> lineTimeList = lineTimeMapper.getLineTime();
//                lineTimeList.forEach(item->{
//                    MigrationParam migration = new MigrationParam();
//                    migration.setLineIds(Collections.singletonList(item.getLineIndex()));
//                    migration.setStartTime(item.getUpdateTime().minusHours(2));
//                    migration.setEndTime(item.getUpdateTime());
//                    System.out.println("当前监测点为------------------------------------"+item.getLineIndex());
//                    System.out.println("执行扫描起始时间------------------------------------"+item.getUpdateTime().minusHours(2).format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
//                    System.out.println("执行扫描结束时间------------------------------------"+item.getUpdateTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
//                    list.addAll(executor.queryData(migration));
//                });
                System.out.println("查询到的数据++++++++++++++"+list.size());
                //反射獲取linid的值并把linid的值替换成mysql对应的linid，并记录未匹配的lineid
                Iterator iterator = list.iterator();
                while (iterator.hasNext()) {
                    try{
                        Object obj = iterator.next();
                        //获取
                        Field id = obj.getClass().getDeclaredField("lineid");
                        id.setAccessible(true); //暴力访问id
                        String id1 = id.get(obj).toString();
                        if (!LineIdMapping.containsKey(id1)){
                            log.info(tableName+"表---Oralcet数据同步到InfluxDB未找mysql中到lineid匹配的lineid"+id1);
                            iterator.remove();
                        }else {
                            id.set(obj,LineIdMapping.get(id1));
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
            //采用弱引用接受，后续手动调用gc后，会清空该对象
            WeakReference<List> weakReferenceData = new WeakReference<>(list);
            int size = 0;
            if (CollectionUtil.isNotEmpty(weakReferenceData.get())) {
                size = weakReferenceData.get().size();
            }
            System.out.println(tableName + "查到" + size + "条数据后总堆内存为：" + runtime.totalMemory() / (1024 * 1024) + " MB");
            System.out.println(tableName + "查到" + size + "条数据后已用堆内存为：" + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + " MB");
            System.out.println(tableName + "查到" + size + "条数据后空闲堆内存为：" + runtime.freeMemory() / (1024 * 1024) + " MB");
            try {
                if (CollectionUtil.isNotEmpty(weakReferenceData.get())) {
                    //执行目标库的数据处理
                    Class<?> clazz;
                    Class<?> clazz2;
                    //获取Table表对应的influxdb对应的表的实体类调用oralceToInfluxDB方法及oralceToInfluxDB的入参clazz2
                    try {
                        clazz = Class.forName("com.njcn.influx.bo.po.InfluxDB" + tableName);
                        clazz2 = Class.forName("com.njcn.oracle.bo.po." + tableName);
                    } catch (ClassNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                    Method method;
                    try {
                        method = clazz.getDeclaredMethod("oralceToInfluxDB", clazz2);
                    } catch (NoSuchMethodException e) {
                        throw new RuntimeException(e);
                    }
                    method.setAccessible(true);
                    Method finalMethod = method;
                    List list1 = (List) weakReferenceData.get().stream().flatMap(po -> {
                        try {
                            Object invoke = finalMethod.invoke(null, po);
                            Object invoke1 = invoke;
                            //返回oracle转influx，flicker等表是1-1，还有1-4，这是判断返回是否是集合如何是集合继续扁平化
                            return invoke1 instanceof List ? ((List<?>) invoke1).stream() : Stream.of(invoke1);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }).collect(Collectors.toList());
                    //插入influxdb
                    influxDBBaseService.insertBatchBySlice(tableName, list1, 10000);
                    //最后一片时修改状态
                }
                //手动执行GC
                System.gc();
                stopWatch.stop();
//                jobDetailInfluxDBHours.setRowCount(size);
//                jobDetailInfluxDBHours.setState(1);
//                jobDetailInfluxDBHours.setDuration(stopWatch.getTotalTimeSeconds());
//                jobDetailHoursInfluxDBService.updateByMultiId(jobDetailInfluxDBHours);
            } catch (Exception exception) {
                exception.printStackTrace();
//                jobDetailInfluxDBHours.setState(2);
//                jobDetailInfluxDBHours.setUpdateTime(LocalDateTime.now());
//                jobDetailHoursInfluxDBService.updateByMultiId(jobDetailInfluxDBHours);
            }
            System.out.println("执行后总堆内存为：" + runtime.totalMemory() / (1024 * 1024) + " MB");
            System.out.println("执行后已用堆内存为：" + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + " MB");
            System.out.println("执行后空闲堆内存为：" + runtime.freeMemory() / (1024 * 1024) + " MB");


        });
    }

    @Override
    @Async
    public void AsyncData(DataAsynParam dataAsynParam) {
        LocalDateTime startDateTime1 = dataAsynParam.getStartDateTime();
        LocalDateTime endDateTime1 = dataAsynParam.getEndDateTime();
        while (endDateTime1.isBefore(startDateTime1)) {
            startDateTime1 = startDateTime1.minusHours(1);
            DataAsynParam dataAsynParam1 = new DataAsynParam();
            dataAsynParam1.setEndDateTime(startDateTime1.minusHours(-1).minusSeconds(1));
            dataAsynParam1.setStartDateTime(startDateTime1);
            if(CollUtil.isEmpty(dataAsynParam.getTableNames())){
                dataAsynParam1.setTableNames(TableEnum.getExecutableTypes());
            }else{
                dataAsynParam1.setTableNames(dataAsynParam.getTableNames());
            }
            log.info("执行"+startDateTime1+"时刻数据");
            this.hourseDataBacthSysc(dataAsynParam1);
        }
    }



    @Override
    public void oneMonitorDataTransport(DataAsynParam dataAsynParam) {
        Map<String, String> LineIdMapping = (Map<String, String>) redisUtil.getObjectByKey("LineIdMapping");
        List<Integer> oracleLineIdList = LineIdMapping.keySet().stream().map(Integer::parseInt).collect(Collectors.toList());

        Runtime runtime = Runtime.getRuntime();
        System.out.println("开始执行前总堆内存为：" + runtime.totalMemory() / (1024 * 1024) + " MB");
        System.out.println("开始执行前已用堆内存为：" + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + " MB");
        System.out.println("开始执行前空闲堆内存为：" + runtime.freeMemory() / (1024 * 1024) + " MB");
        //目前且作为2片，后续将该属性提取到配置文件中
        List<String> tableNames = dataAsynParam.getTableNames();
        //嵌套循环，先循环指标，再循环日期
        tableNames.stream().forEach(tableName -> {
            IReplenishMybatisService executor;
            try {
                executor = (IReplenishMybatisService) SpringUtil.getBean(Class.forName(PACKAGE_PREFIX + tableName + PACKAGE_SUFFIX));
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            List<LocalDate> dateList = LocalDateUtil.getDateList(dataAsynParam.getStartTime(), dataAsynParam.getEndTime());
            for (LocalDate date : dateList) {

                //分片下，每段时间的小时数
                int sliceHour = 24 / slice;
                for (int i = 0; i < slice; i++) {
                    String dateStr = LocalDateTimeUtil.format(date, DatePattern.NORM_DATE_PATTERN);
                    LocalDateTime startTime = LocalDateTimeUtil.parse(dateStr + StrPool.C_SPACE + (sliceHour * i < 10 ? "0" + sliceHour * i : sliceHour * i) + ":00:00", DatePattern.NORM_DATETIME_PATTERN);
                    LocalDateTime endTime = LocalDateTimeUtil.parse(dateStr + StrPool.C_SPACE + (sliceHour * (i + 1) - 1 < 10 ? "0" + (sliceHour * (i + 1) - 1) : sliceHour * (i + 1) - 1) + ":59:59", DatePattern.NORM_DATETIME_PATTERN);
                    //查询该时区的数据，并准备入库
                    MigrationParam migration = new MigrationParam();
                    migration.setStartTime(startTime);
                    migration.setEndTime(endTime);
                    migration.setLineIds(oracleLineIdList);

                    if (Objects.nonNull(dataAsynParam.getMonitorId())) {
                        migration.setLineIds(Stream.of(dataAsynParam.getMonitorId()).collect(Collectors.toList()));
                    }

                    List list = executor.queryData(migration);
                    //反射獲取linid的值并把linid的值替换成mysql对应的linid，并记录未匹配的lineid
                    Iterator iterator = list.iterator();
                    while (iterator.hasNext()) {
                        try {
                            Object obj = iterator.next();
                            //获取
                            Field id = obj.getClass().getDeclaredField("lineid");
                            id.setAccessible(true); //暴力访问id
                            String id1 = id.get(obj).toString();
                            if (!LineIdMapping.containsKey(id1)) {
                                log.info(tableName + "表---Oralcet数据同步到InfluxDB未找mysql中到lineid匹配的lineid" + id1);
                                iterator.remove();
                            } else {
                                id.set(obj, LineIdMapping.get(id1));
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }

                    //采用弱引用接受，后续手动调用gc后，会清空该对象
                    WeakReference<List> weakReferenceData = new WeakReference<>(list);
                    int size = 0;
                    if (CollectionUtil.isNotEmpty(weakReferenceData.get())) {
                        size = weakReferenceData.get().size();
                    }
                    System.out.println(tableName + "查到" + size + "条数据后总堆内存为：" + runtime.totalMemory() / (1024 * 1024) + " MB");
                    System.out.println(tableName + "查到" + size + "条数据后已用堆内存为：" + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + " MB");
                    System.out.println(tableName + "查到" + size + "条数据后空闲堆内存为：" + runtime.freeMemory() / (1024 * 1024) + " MB");
                    try {
                        if (CollectionUtil.isNotEmpty(weakReferenceData.get())) {
                            //执行目标库的数据处理
                            Class<?> clazz;
                            Class<?> clazz2;
                            //获取Table表对应的influxdb对应的表的实体类调用oralceToInfluxDB方法及oralceToInfluxDB的入参clazz2
                            try {
                                clazz = Class.forName("com.njcn.influx.bo.po.InfluxDB" + tableName);
                                clazz2 = Class.forName("com.njcn.oracle.bo.po." + tableName);
                            } catch (ClassNotFoundException e) {
                                throw new RuntimeException(e);
                            }
                            Method method;
                            try {
                                method = clazz.getDeclaredMethod("oralceToInfluxDB", clazz2);
                            } catch (NoSuchMethodException e) {
                                throw new RuntimeException(e);
                            }
                            method.setAccessible(true);
                            Method finalMethod = method;
                            List list1 = (List) weakReferenceData.get().stream().flatMap(po -> {
                                try {
                                    Object invoke = finalMethod.invoke(null, po);
                                    Object invoke1 = invoke;
                                    //返回oracle转influx，flicker等表是1-1，还有1-4，这是判断返回是否是集合如何是集合继续扁平化
                                    return invoke1 instanceof List ? ((List<?>) invoke1).stream() : Stream.of(invoke1);
                                } catch (Exception e) {
                                    throw new RuntimeException(e);
                                }
                            }).collect(Collectors.toList());
                            //插入influxdb
                            influxDBBaseService.insertBatchBySlice(tableName, list1, 10000);
//                            size = list1.size();
                            //最后一片时修改状态
                        }
                        //手动执行GC
                        System.gc();

                    } catch (Exception exception) {
                        exception.printStackTrace();
                    }
                    System.out.println("执行后总堆内存为：" + runtime.totalMemory() / (1024 * 1024) + " MB");
                    System.out.println("执行后已用堆内存为：" + (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024) + " MB");
                    System.out.println("执行后空闲堆内存为：" + runtime.freeMemory() / (1024 * 1024) + " MB");
                }
            }
        });
    }
}
