两个不同数据库中的数据可以通过一个字段关联,要实现用a表的一个字段去b表中对应的接口进过一系列查询后获取到一个编号,最后反写到a表中。
直接使用sql连表查询是实现不了的,只能掉对应b表中的接口,接口只提供了一个字段的查询方法,没有提供批量的查询方法,同时a表中的数据接近10万条,一条条的掉需要程序跑很久这时候就需要多线程来实现了。
首先在SpringBoot的启动类上标记@EnableAsync 注解开启多线程。
然后正常的写方法是定时任务或者弄一个请求路径主动去触发。
@RequestMapping(value = "/ythq",method = RequestMethod.GET)
public void getDistrict() {
int c= service.DistrictCount();//获取数据总量
if(c<=0){
System.out.println("查询总数量失败");
return;
}
System.out.println("查询总数量为"+c);
List<HashMap> hashMaps = service.selectDistrictInfo(c);//获取到详细的数据
//将数据进行500条一开启一个线程去调用
int discuss = (int)Math.floor(c/500);//向上取整
int remainder= c%500;//不足500的数据条数
for (int i = 0; i < discuss; i++) {
List<HashMap> clsj = new ArrayList<>();
if (i==discuss-1 && remainder>1){
clsj=hashMaps.subList(500*i, (500*(i+1))+remainder);
}else {
clsj= hashMaps.subList(500*i, 500*(i+1));
}
service.executeDistrictBase(clsj,i);
}
}
最后在调用B表的接口方法上标记 @Async注解实现多线程
@Async
public void executeDistrictBase(List<HashMap> clsj,int i) {
for (HashMap map : clsj) {
if (map.get("FWBH")==null){
log.info("\n这个是第"+i+"个异步调用线程,操作的数据为"+map+"fwbh为空,不处理");
continue;
}
LinkedMultiValueMap<String,String> requestBody = new LinkedMultiValueMap();
requestBody.add("key",map.get("value").toString());
String str = InterfaceRequest(URL", requestBody);//调用接口方法,获取返回值
JSONObject resultJson = JSONObject.parseObject(str);
try{
Integer fwbh = restRequest(resultJson, map.get("key").toString());//执行插入操作
if (fwbh>0) {
log.info("\n这个是第" + i + "个异步调用线程,操作的数据为" + map + ",接口返回数据" + str + "插入成功");
}else {
log.info("\n这个是第" + i + "个异步调用线程,操作的数据为" + map + ",接口返回数据" + str + "插入失败");
}
}catch (Exception e){
log.error("\n这个是第"+i+"个异步调用线程,操作的数据为"+map+",接口返回数据"+str+"插入异常:"+e);
}
}
}
远程接口的调用参考远程接口调用
后期优化空间:可以将一个请求返回的值存起来,等500条数据获取完后将数据批量提交,可以降低对a数据库操作的次数提升性能。