Java分页思想在分批次入库和多线程操作中的应用

    java web分页思想很常用,本质思想是:由于数据量太大,一页显示不完的,所以需要分页显示。那么分页核心就是如何计算每一页的起始下标。

    分页思想总结起来就是分批次处理,除了用在web页面的分页,还适用于数据库入库和多线程操作等应用场景。

    只要掌握了其原理,便可举一反三。

    解析开始:

   1.总共有 len 条数据,但每次只能处理 batchSize 条记录,所以需要分为 times 次来处理。

   a.如果能整除比较简单:

                times = len / batchSize

   b.如果不能整除,只需要把余数单独作为一轮来处理就行了:              

               if(len%batchSize != 0) //如果不能整除,则要多跑一轮

                     times++;

 

/哈哈分割线/  

2.当把批次确定好了之后,接下来计算每一轮的起始和结束下标即可。

//以len=32,batchSize=10,times=(32/10)+1=4 为例

(PS粗心的同学:整型数据相除舍去小数位,只取整数据位)

那么第一轮:[0 --9]  

   ​    ​第二轮:[10 -- 19]   //个位数是不是很规律:-)

   ​    ​第三轮:[20 --29]

   ​    ​第四轮:[30 -- 31]

或者:

   ​    ​第一轮:[1 -- 10]  

       第二轮:[11 --20]   //个位数是不是很规律:-)

       第三轮:[21 --30]

       第四轮:[31 -- 32]

/哈哈分割线/ 

so,下面上代码:

a.下标从0开始计算的情况   

for(int i=1; i<=times; i++)

{     

       start= (i-1)*batchSize;   //=0, 10, 20, 30

       end= start + batchSize; //=10 ,20, 30, 32

       if(end>=len) //最后一轮数据未满,所以end 要特殊处理

              end= len;

 

       //这个是开区间[start,end),这个区间内的数据就是本轮要处理的数据

       do something(start,end)//传入区间参数,调用函数完成计算

b.下标从1开始计算的情况

for(int i=1; i<=times;  i++)

{

       start= (i-1)*batchSize+1; //=1 ,11, 21,31

       end= start + batchSize-1; //=10, 20,30,32

       if(end>=len) //最后一轮数据未满,所以end 要特殊处理

              end= len;

       

      //这个是闭区间[start,end],这个区间内的数据就是本轮要处理的数据

       do something(start,end)//传入区间参数,调用函数完成计算

 

下面贴上源代码:

a.下标从0开始计算的情况   

/**
     * 利用分页思想, 分批次入库
     * @Title: batchWriteDB 
     * @param list  list表数据过大,需要分批入库
     * @param batchSize	每轮入库数据量
     * @param sp	spark api
     * @param tbName	表名
     * @param beanClass	表的bean对象
     */
    public static <T> void batchWriteDB(List<T> list,int batchSize,SparkApi sp, String tbName, Class<T> beanClass)
    {
    	int len = list.size();//总数
    	int times = len/batchSize;//轮数
	if(len%batchSize != 0)//如果不能整除,则要多跑一轮
	        times++;
		
	Log.log("-----总共"+len+" 条记录总需要分为"+times+" 轮来入库,每轮写入"+batchSize+" 条记录");	
	int start = 1;
	int end = 1;
		
	for(int i=1;i<=times; i++)
	{
	    start = (i-1)*batchSize;
	    end = start + batchSize;
	    if(end>=len)//最后一轮数据未满
	        end = len;
			 
	    //子集为开区间[0,len)  =[0, len-1]
	    List<T> list2 = list.subList(start,end);
	    Log.log("第"+i+"轮入库:list2.size()= "+list2.size()+",  list.size()="+list.size());
	    Log.log("start="+start+", end="+end+" length="+(end-start));  
			
            Dataset<Row> squaresDF = sp.createDataFrame(list2, beanClass);
            squaresDF.coalesce(Config.nSparkCores).write().partitionBy("timeh").mode(SaveMode.Append).saveAsTable(tbName);
            squaresDF = null;           
         }
    }

b.下标从1开始计算的情况

public static void hbaseMultiInsert(int dataNum,int ThreadNum) throws InterruptedException 
{	
      if(dataNum%ThreadNum!=0)//如果不能整除,则要多跑一轮
            ThreadNum ++; 
      int pageSize  = dataNum/ThreadNum;//分页思想:每轮执行多少数据
            int start = 1;
	    int end = 1;
	    //同步器
	   final CountDownLatch cdl = new CountDownLatch(ThreadNum);
	   long starttime=System.currentTimeMillis();
	   for(int k=1;k<=ThreadNum;k++)
	   {
		  start = (k-1)*pageSize+1;
		  end = start+pageSize-1;
		  if(end>=dataNum)//最后一轮数据未满
		       	end = dataNum;
		  
		  //extends Thread这样调用
		  new MyThread(cdl,start,end).start();
			  
		 /*
		  //MyThread implements Runnable这样调用
		  MyThread my = new MyThread(start,end);			  
		  Thread thread = new Thread(my); 
		  thread.start();
		 */
            }
          try {
	      cdl.await();
	      long spendtime=System.currentTimeMillis()-starttime;
	      System.out.println( ThreadNum+"个线程花费时间:"+spendtime/1000.0);
	  } catch (InterruptedException e) {
		      e.printStackTrace();
	  }	  
		
}//hbaseMultiInsert

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值