美文网首页程序员
JAVA多线程分页(两个线程)替代union

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

作者: Levine_8582 | 来源:发表于2020-08-25 10:44 被阅读0次

需求来源

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

相关文章

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

    需求来源 日常开发中经常遇到不同数据表通过union方式关联在一起查询,但是在数据量大的时候union的弊端就显露...

  • Java多线程目录

    Java多线程目录 Java多线程1 线程基础Java多线程2 多个线程之间共享数据Java多线程3 原子性操作类...

  • 带你搞懂Java多线程(五)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四) ...

  • 带你搞懂Java多线程(六)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四)带...

  • 线程(Thread)

    Java 多线程编程 Java 给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的...

  • 带你搞懂Java多线程(四)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三) 什么是线程间的协作 线程之间...

  • 学习Java多线程编程前必须要掌握的概念

    Java是一种多线程编程语言,我们可以使用Java来开发多线程程序。 多线程程序包含两个或多个可同时运行的部分,每...

  • 1 Java并发是什么?

    Java是一种多线程编程语言,我们可以使用Java来开发多线程程序。 多线程程序包含两个或多个可同时运行的部分,每...

  • Java多线程

    Java 多线程编程Java 给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的每...

  • Java多线程

    Java 多线程编程 Java给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的每...

网友评论

    本文标题:JAVA多线程分页(两个线程)替代union

    本文链接:https://www.haomeiwen.com/subject/uvpajktx.html