需求来源
日常开发中经常遇到不同数据表通过union方式关联在一起查询,但是在数据量大的时候union的弊端就显露了出来,数据查询慢。如果改成java代码方法分成多个线程去查询,就会出现分页的难题。大家可以百度多线程分页关键字。我在网上找不到合适的解决方案或者能直接使用的代码,于是自己捣鼓了一个,但是只支持两个线程。废话不多说上代码。
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang3.ObjectUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* @author tshk
* @date 2020-08-18 09:20
*/
@Data
public class ThreadPageHelper {
@ApiModelProperty("线程1偏移量")
private Integer oneOffSet;
@ApiModelProperty("线程1补页量")
private Integer oneLimit;
@ApiModelProperty("线程2偏移量")
private Integer twoOffSet;
@ApiModelProperty("线程2补页量")
private Integer twoLimit;
@ApiModelProperty("线程1是否能查询")
private boolean oneCanQuery;
@ApiModelProperty("线程2是否能查询")
private boolean twoCanQuery;
@ApiModelProperty("总条数")
private Long total;
public ThreadPageHelper(Integer theadOneCount,Integer theadTwoCount,Integer page,Integer pageSize){
theadOneCount= ObjectUtils.defaultIfNull(theadOneCount,0);
theadTwoCount=ObjectUtils.defaultIfNull(theadTwoCount,0);
page=page==null||page<0?1:page;
pageSize=ObjectUtils.defaultIfNull(pageSize,0);
BigDecimal size = new BigDecimal(pageSize);
int oneSize=size.divide(new BigDecimal(2), RoundingMode.UP).intValue();
int twoSize=size.divide(new BigDecimal(2), RoundingMode.DOWN).intValue();
int afterOffset=(page-1)*oneSize+(theadTwoCount-(page-1)*twoSize<0?(page-1)*twoSize-theadTwoCount:0);
int beforeOffset=(page-1)*twoSize+(theadOneCount-(page-1)*oneSize<0?(page-1)*oneSize-theadOneCount:0);
int afterTmp = theadOneCount-afterOffset;
int beforeTmp = theadTwoCount-beforeOffset;
int afterOffsetLimit=afterTmp-oneSize>0?0:afterOffset-theadOneCount>oneSize?oneSize:(theadOneCount-afterOffset)<=0?oneSize:oneSize-(theadOneCount-afterOffset);
int beforeOffsetLimit=beforeTmp-twoSize>0?0:beforeOffset-theadTwoCount>twoSize?twoSize:(theadTwoCount-beforeOffset)<=0?twoSize:twoSize-(theadTwoCount-beforeOffset);
afterOffset=afterOffset>=theadOneCount?0:afterOffset;
beforeOffset=beforeOffset>=theadTwoCount?0:beforeOffset;
this.oneOffSet=afterOffset;
this.twoOffSet=beforeOffset;
this.oneLimit=oneSize+beforeOffsetLimit;
this.twoLimit=twoSize+afterOffsetLimit;
this.oneCanQuery=!(page!=1 && this.oneOffSet ==0);
this.twoCanQuery=!(page!=1 && this.twoOffSet ==0);
this.total= (long) (theadOneCount + theadTwoCount);
}
}
使用教程
CountDownLatch latch=new CountDownLatch(2);
Integer oneCount = oneMapper.searchRecordCount(recordDTO);
Integer twoCount =twoMapper.searchRecordCount(recordDTO);
ThreadPageHelper threadPageHelper=new ThreadPageHelper(oneCount,twoCount,requestDTO.getPage(),requestDTO.getSize());
if(!threadPageHelper.isOneCanQuery()){
latch.countDown();
}else{
TaskManager.addTask(() -> {
if ( !requestDTO.isExport() ) {
PageHelper.offsetPage(threadPageHelper.getOneOffSet(),threadPageHelper.getOneLimit(),false);
}
List<Record> records = oneMapper.searchRecord(recordDTO);
recordsA.set(records);
latch.countDown();
});
}
if(!threadPageHelper.isTwoCanQuery()){
latch.countDown();
}else {
TaskManager.addTask(() -> {
if (!requestDTO.isExport()) {
PageHelper.offsetPage(threadPageHelper.getTwoOffSet(), threadPageHelper.getTwoLimit(), false);
}
List<Record> twoRecords = twoMapper.searchRecord(recordDTO);
recordsB.set(twoRecords);
latch.countDown();
});
}
try {
latch.await();
} catch (InterruptedException e) {
logger.error("查询数据出错{}",e);
}
网友评论