JAVA多线程分页(两个线程)替代union

需求来源

日常开发中经常遇到不同数据表通过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);
					}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值