java 实现增量同步和自定义同步的操作
场景
公司有多个系统。需要从某个系统拿数据。初始化拿一次,然后每天增量同步。
因为逻辑关系有些复杂,且涉及到多表,所以纯sql不太方便。
项目之前的mybatis写死了,sysdate-1的数据。
如何全量同步
老办法
可以让某系统调整modifyDate,本系统通过定时任务同步这些数据。
缺点:按规定不允许改数据,别人也不乐意改。
较好的办法
调整mybatis,传入参数变为自定义方法,这样就可以同步任意时刻的数据。
一般有2种方法:
传入游标方法:sysdate-n
直接传入日期字符串:modifyDatebetween‘888'and‘999'
然后增加request请求,手动调用同步方法。
补充:java数据同步,增量更新表中记录数据
背景:
我方系统中的数据从第三方系统同步过来。双方通过json格式交互,数据格式如下:
{
"resInfo":{"code":"0","msg":"查询成功"},
"columns":"requestId,jobNumber,requestDate,department,businessDays,cfd,mdd,startTime,endTime,reason,remark",
"data":[
{"requestId"="11925","jobNumber"="5721","requestDate"="2019-05-06","department"="57","businessDays"="21","cfd"="上海","mdd"="南京","startTime"="2019-05-0613:36","endTime"="2019-05-0713:36","reason"="","remark"=""}
]
}
增量更新处理思路:
1、调用第三方接口,获取数据,做解析,得到一个List1。
2、查询数据库出差表,得到另一个List2。
3、两个list做比较,获取不同的元素列表。
list2-list1:要删除的记录。
list1-list2:要新增的记录。
主要实现代码:
Stringresult="调用接口返回的json串";//参见交互的json数据格式
ResultObjectresultObject=JSON.parseObject(result,newTypeReference >(){ }); List list=resultObject.getData(); if(!CollectionUtils.isEmpty(list)){ //查询数据库记录条数 List list2=businessService.queryBusinessTripList(); Map >map=ListUtils.getMap(list,list2); //删除出差 List newRemoveList=map.get(ListUtils.LIST2_REMOVE_LIST1); if(!CollectionUtils.isEmpty(newRemoveList)){ List newChangeList2=newRemoveList.stream().map(item->item.getRequestId()).collect(Collectors.toList()); intremoveCount=businessService.batchDeleteBusinessTrip(newChangeList2); log.error("删除出差记录个数,removeCount="+removeCount); } //新增出差 List newAddList=map.get(ListUtils.LIST1_REMOVE_LIST2); if(!CollectionUtils.isEmpty(newAddList)){ intaddCount=businessService.batchInsertBusinessTrip(newAddList); log.error("新增出差记录个数,addCount="+addCount); } }else{ log.error("同步出差申请结束,没有查询到出差数据。"); }
出差实体类BusinessTrip.java
importlombok.Data;
/**
*出差
*/
@Data
publicclassBusinessTrip{
/**
*请求ID
*/
privateStringrequestId;
/**
*工号
*/
privateStringjobNumber;
/**
*申请日期
*/
privateStringrequestDate;
/**
*申请人所在部门id
*/
privateStringdepartment;
/**
*出差天数
*/
privateStringbusinessDays;
/**
*出发地
*/
privateStringcfd;
/**
*目的地
*/
privateStringmdd;
/**
*出差开始时间
*/
privateStringstartTime;
/**
*出差结束时间
*/
privateStringendTime;
/**
*出差事由
*/
privateStringreason;
/**
*备注
*/
privateStringremark;
}
ResultObject.java
/**
*@Name:ResultObject
*@Desc:基类泛型
*@Author:Administrator
*@Date:2019-08-2818:32
*{
"resInfo":{"code":"0","msg":"查询成功"},
"columns":"requestId,jobNumber,requestDate,department,businessDays,cfd,mdd,startTime,endTime,reason,remark",
"data":[
{"requestId"="11925","jobNumber"="5721","requestDate"="2019-05-06","department"="57","businessDays"="21","cfd"="上海","mdd"="南京","startTime"="2019-05-0613:36","endTime"="2019-05-0713:36","reason"="","remark"=""}
]
}
*/
@Data
publicclassResultObject{
privateStringcolumns;
privateResInforesInfo;
privateListdata;
}
ResInfo.java
importlombok.Data;
/**
*@Name:ResInfo
*@Desc
*@Author:Administrator
*@Date:2019-08-2818:38
*{"code":"0","msg":"查询成功"}
*/
@Data
publicclassResInfo{
privateStringcode;
privateStringmsg;
}
ListUtils.java工具类:
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.List;
importjava.util.Map;
importjava.util.stream.Collectors;
/**
*@Name:ListUtils
*@Desc
*@Author:Administrator
*@Date:2019-08-2914:03
*/
publicclassListUtils{
/**
*交集
*/
publicstaticfinalStringLIST1_AND_LIST2="0";
/**
*差集(list1-list2)
*/
publicstaticfinalStringLIST1_REMOVE_LIST2="1";
/**
*差集(list2-list1)
*/
publicstaticfinalStringLIST2_REMOVE_LIST1="2";
publicstaticMap>getMap(Listlist1,Listlist2){
//交集
Listintersection=list1.stream().filter(item->list2.contains(item)).collect(Collectors.toList());
//差集(list1-list2)
Listreduce1=list1.stream().filter(item->!list2.contains(item)).collect(Collectors.toList());
//差集(list2-list1)
Listreduce2=list2.stream().filter(item->!list1.contains(item)).collect(Collectors.toList());
Map>map=newHashMap<>();
map.put(LIST1_AND_LIST2,intersection);
map.put(LIST1_REMOVE_LIST2,reduce1);
map.put(LIST2_REMOVE_LIST1,reduce2);
returnmap;
}
//publicstaticvoidmain(String[]args){
//Listlist1=newArrayList<>();
//list1.add("1111");
//list1.add("2222");
//list1.add("3333");
//list1.add("4444");
//
//Listlist2=newArrayList<>();
//list2.add("3333");
//list2.add("4444");
//list2.add("5555");
//list2.add("6666");
//
//Map>map=getMap(list1,list2);
//System.out.println(map);
//}
}
实际处理过程中出现的一个问题是:
接口返回的字段中,不是每个字段都有值。在第一次插入数据后,再查询时,字段得到的值是null,不是空串。
操作中出现一个问题:
接口中拿到的数据是这样:
BusinessTrip(requestId=11925,jobNumber=5721,requestDate=2019-05-06,department=57,businessDays=21,cfd=上海,mdd=南京,startTime=2019-05-0613:36,endTime=2019-05-0713:36,reason=,remark=)
就是通过mybatis查询出的数据,得到记录格式是这样。
BusinessTrip(requestId=11925,jobNumber=5721,requestDate=2019-05-06,department=57,businessDays=21,cfd=上海,mdd=南京,startTime=2019-05-0613:36,endTime=2019-05-0713:36,reason=null,remark=null)
两个格式差别是,部分字段,比如reason字段,一个是空串,一个是null,导致List中元素在做比较的时候,总是不相等。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。