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; privateList data; }
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(List list1,List list2){ //交集 List intersection=list1.stream().filter(item->list2.contains(item)).collect(Collectors.toList()); //差集(list1-list2) List reduce1=list1.stream().filter(item->!list2.contains(item)).collect(Collectors.toList()); //差集(list2-list1) List reduce2=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){ //List list1=newArrayList<>(); //list1.add("1111"); //list1.add("2222"); //list1.add("3333"); //list1.add("4444"); // //List list2=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中元素在做比较的时候,总是不相等。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。