package com.example.consumer.manager.ibb;
import com.example.constant.DebitCardConstant;
import com.example.consumer.manager.kbb.QueryCustomerHoldSettlementCardInfoKBBManager;
import com.example.dao.DebitCardContractDAO;
import com.example.dao.DebitCardDAO;
import com.example.entity.DebitCardBO;
import com.example.entity.DebitCardContractBO;
import com.example.request.QueryDebitCardRequest;
import com.example.response.QueryDebitCardResponseVO;
import com.example.vo.ComposeResultFirstVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
/**
* 客户名下的卡片信息
* 根据客户号 查询卡片信息
* 客户号 = 卡片信息中的 客户号
* 获取合约编号
*/
@Component
public class QueryCustomerHoldSettlementCardInfoIBBManager {
@Autowired
DebitCardContractDAO debitCardContractDAO;
@Autowired
DebitCardDAO debitCardDAO;
@Autowired
QueryCustomerHoldSettlementCardInfoKBBManager queryCustomerHoldSettlementCardInfoKBBManager;
/**
* 客户号 = 《合约表》单位持卡人编号 再 查询卡片表
* @param queryDebitCardRequest
* @return
*/
public QueryDebitCardResponseVO queryCustomerUnderDebitCardInfo(QueryDebitCardRequest queryDebitCardRequest){
Integer pageSize = 10;
if(StringUtils.isEmpty(queryDebitCardRequest.getPageSize())){
pageSize = Integer.parseInt(queryDebitCardRequest.getPageSize());
}
Integer pageNo = 1;
if(StringUtils.isEmpty(queryDebitCardRequest.getPageNo())){
pageNo = Integer.parseInt(queryDebitCardRequest.getPageNo());
}
String validFlag = queryDebitCardRequest.getValidFlag();
String contractNo = queryDebitCardRequest.getCusNo();
//根据 客户号 = 单位持卡人编号 获取合约信息
List<DebitCardContractBO> debitCardContractBOList = debitCardContractDAO.selectByContractNo(contractNo);
//获取合约信息中的合约编号用于查询卡片表
List<String> list = new ArrayList<>(0);
if(!CollectionUtils.isEmpty(debitCardContractBOList)){
list = debitCardContractBOList.stream().map(t->t.getDbcrdArRefno()).collect(Collectors.toList());
}
List<DebitCardBO> debitCardList = pageCycleQueryUseThread(list);
//查询所有的卡片表信息后 过滤
if(!CollectionUtils.isEmpty(debitCardList)){
debitCardList = getDebitCardBOList(debitCardList,validFlag);
}
//组装信息
List<ComposeResultFirstVO> mapList = queryCustomerHoldSettlementCardInfoKBBManager.queryCustomerUnderCardInfo(debitCardList,debitCardContractBOList);
QueryDebitCardResponseVO responseVO = new QueryDebitCardResponseVO();
int totalRecords = 0;
if(!CollectionUtils.isEmpty(mapList)){
totalRecords = debitCardContractBOList.size();
}
int totalPages = totalRecords/pageSize;
if(totalRecords % pageSize != 0){
totalPages++;
}
responseVO.setPageNo(pageNo);
responseVO.setList(mapList);
responseVO.setTotalRecords(totalRecords);
responseVO.setTotalPages(totalPages);
return responseVO;
}
/**
* @description:
* @author: Bruce_T
* @param debitCardBOList
* @data: 2022/2/14 10:05
* @modified:
*/
private List<DebitCardBO> getDebitCardBOList(List<DebitCardBO> debitCardBOList,String validFlag){
//有效
if("1".equals(validFlag)){
debitCardBOList.stream().filter(u->DebitCardConstant.DEBIT_CARD_LIFECYCLE_00506.getCode().equals(u.getCardLifeCycle())).collect(Collectors.toList());
}
//无效
if("0".equals(validFlag)){
debitCardBOList.stream().filter(u->!DebitCardConstant.DEBIT_CARD_LIFECYCLE_00506.getCode().equals(u.getCardLifeCycle())).collect(Collectors.toList());
}
return debitCardBOList;
}
/**
* 合约集合中循环查询 卡片信息,in(合约编号)(不是卡片表的主键)
* 采用多线程
* 前闭后开
* 取前5条数据
* select * from table_name limit 0,5
* 查询第11到第15条数据
* select * from table_name limit 10,5
* limit关键字的用法:
* LIMIT [offset,] rows
* offset指定要返回的第一行的偏移量,rows第二个指定返回行的最大数目。初始行的偏移量是0(不是1)。
* select * from t_table limit #{index},#{num}
* public List<T> queryByThread(@Param(value = "index")int index, @Param(value = "num")int num);
*
* @param list
* @return
*/
private List<DebitCardBO> pageCycleQueryContractBO(List<String> list){
//数据集合大小
Integer listSize = list.size();
//开启的线程数
Integer runSize = 10;
// 一个线程处理数据条数,如果库中有100条数据,开启20个线程,那么每一个线程执行的条数就是5条
int count = listSize / runSize;//5
// 创建一个线程池,数量和开启线程的数量一样
ExecutorService executor = Executors.newFixedThreadPool(runSize);
// 计算sql语句中每个分页查询的起始和结束数据下标
// 循环创建线程
List<DebitCardBO> resultList = new ArrayList<>(0);
//此处调用具体的查询方法
for (int i = 0; i < runSize; i++) {
int index = i * count;
int num = count;
Future<List<DebitCardBO>> future = executor.submit(new Callable<List<DebitCardBO>>() {
@Override
public List<DebitCardBO> call() throws Exception {
List<DebitCardBO> resultList = debitCardDAO.selectByThread(index, num);
return resultList;
}
});
try {
List<DebitCardBO> debitCardBOList = future.get();
resultList.addAll(debitCardBOList);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
// 执行完关闭线程池
executor.shutdown();
return resultList;
}
/**
* @description:
* @author: Bruce_T
* @param * @param null
* @return {@link null}
* @data: 2022/2/14 11:33
* @modified:
*/
private List<DebitCardBO> pageCycleQueryContractBO2222(List<String> list){
//数据集合大小
Integer listSize = list.size();
//开启的线程数
Integer runSize = 3;
// 一个线程处理数据条数,如果库中有100条数据,开启20个线程,那么每一个线程执行的条数就是5条
int count = listSize / runSize;//5
// 创建一个线程池,数量和开启线程的数量一样
ExecutorService executor = Executors.newFixedThreadPool(runSize);
// 计算sql语句中每个分页查询的起始和结束数据下标
// 循环创建线程
List<DebitCardBO> resultList = new ArrayList<>(0);
//此处调用具体的查询方法
for (int i = 0; i < runSize; i++) {
int index = i * count;
int num = count;
Future<List<DebitCardBO>> future = executor.submit(new Callable<List<DebitCardBO>>() {
@Override
public List<DebitCardBO> call() throws Exception {
List<DebitCardBO> resultList = debitCardDAO.selectListByThread(list);
return resultList;
}
});
try {
List<DebitCardBO> debitCardBOList = future.get();
resultList.addAll(debitCardBOList);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
// 执行完关闭线程池
executor.shutdown();
return resultList;
}
/**
* @description: 不适用多线程
* @author: Bruce_T
* @param list
* @return {@link null}
* @data: 2022/2/14 10:07
* @modified:
*/
private List<DebitCardBO> pageCycleQuery(List<String> list){
List<DebitCardBO> resultList = new ArrayList<>();
if(list.size() == 1){
resultList.add(debitCardDAO.selectDebitCardByPrimaryKey("003",list.get(0)));
return resultList;
}
Integer total = list.size();
Integer size = 50;
Integer pages = total % size == 0 ? total/size : total/size +1;
for(int i = 0; i<pages ;i++){
Integer toIndex = (i+1)*size > total ? total : (i+1)*size;
//分批查询
List<DebitCardBO> tempList = debitCardDAO.selectDebitCardByMutipleContractId(list.subList(i * size, toIndex));
//组装结果
resultList.addAll(tempList);
}
return resultList;
}
/**
* @description: 使用多线程并发处理
* @author: Bruce_T
* @param * @param null
* @return {@link null}
* @data: 2022/2/14 10:11
* @modified:
*/
private List<DebitCardBO> pageCycleQueryUseThread(List<String> list){
List<DebitCardBO> resultList = new ArrayList<>();
//数据集合大小
Integer total = list.size();
Integer size = 5;
//开启的线程数 = 总页数
Integer runSize = total % size == 0 ? total/size : total/size +1;
// 一个线程处理数据条数,如果库中有100条数据,开启20个线程,那么每一个线程执行的条数就是5条
int count = total / runSize;//5
//总页数
// Integer pages = total % size == 0 ? total/size : total/size + 1;
// 创建一个线程池,数量和开启线程的数量一样
ExecutorService executor = Executors.newFixedThreadPool(runSize);
for(int i = 0; i<runSize ; i++){
Integer toIndex = (i+1)*size > total ? total : (i+1)*size;
int finalI = i;
Future<List<DebitCardBO>> future = executor.submit(() -> {
List<DebitCardBO> resultList1 = debitCardDAO.selectListByThread(list.subList(finalI * size, toIndex));
return resultList1;
});
try {
List<DebitCardBO> debitCardBOList = future.get();
resultList.addAll(debitCardBOList);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
// 执行完关闭线程池
executor.shutdown();
return resultList;
}
}
lambda组合数据
package com.example.consumer.manager.kbb;
import com.example.entity.DebitCardBO;
import com.example.entity.DebitCardContractBO;
import com.example.vo.ComposeResultFirstVO;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Component
public class QueryCustomerHoldSettlementCardInfoKBBManager {
/**
*
* @param debitCardBOS
* @param contractBOList
* @return
*/
public List<ComposeResultFirstVO> queryCustomerUnderCardInfo(List<DebitCardBO> debitCardBOS, List<DebitCardContractBO> contractBOList) {
List<ComposeResultFirstVO> collect = contractBOList.stream().flatMap(x -> {
// 如果list2不包含list1的commonId 或 list2为空,map.put(x)
if (CollectionUtils.isEmpty(debitCardBOS) || debitCardBOS.stream().noneMatch(i -> !StringUtils.isEmpty(x.getDbcrdArRefno()) && x.getDbcrdArRefno().equals(i.getDbcrdArRefno()))) {
return whenCardBOIdNull(x);
}
//根据合约编号合并数据
return debitCardBOS
.stream()
.filter(y -> !StringUtils.isEmpty(x.getDbcrdArRefno()) && x.getDbcrdArRefno().equals(y.getDbcrdArRefno())).map(j -> whenCardBOIdNotNull(x, j));
}
).collect(Collectors.toList());
//排序-改变原来的集合
collect.sort(Comparator.comparing(ComposeResultFirstVO::getIssueDate).reversed());
// collect.stream().sorted(Comparator.comparing(ComposeResultFirstVO::getIssueDate).reversed());
//分页
int pageSize = 10;
int pageNo = 1;
collect = collect.stream().skip(pageSize * (pageNo - 1)).limit(pageSize).collect(Collectors.toList());
return collect;
}
/**
* @description:
* @author: Bruce_T
* @param * @param null
* @return {@link null}
* @data: 2022/2/14 11:29
* @modified:
*/
private Stream<ComposeResultFirstVO> whenCardBOIdNull(DebitCardContractBO x){
ComposeResultFirstVO composeResultFirstVO = new ComposeResultFirstVO();
composeResultFirstVO.setContractNo(x.getDbcrdArRefno());
composeResultFirstVO.setCusNo(x.getCusno());
composeResultFirstVO.setCompanyHoldNo(x.getCscdCrdhlRefno());
composeResultFirstVO.setCardLifeCycle("");
composeResultFirstVO.setIssueDate(x.getIssueDate());
composeResultFirstVO.setSaleableProductCode(x.getLgperCode());
return Stream.of(composeResultFirstVO);
}
/**
* @description:
* @author: Bruce_T
* @param * @param null
* @return {@link null}
* @data: 2022/2/14 11:29
* @modified:
*/
private ComposeResultFirstVO whenCardBOIdNotNull(DebitCardContractBO x,DebitCardBO j){
ComposeResultFirstVO composeResultFirstVO = new ComposeResultFirstVO();
composeResultFirstVO.setContractNo(x.getDbcrdArRefno());
composeResultFirstVO.setCusNo(x.getCusno());
composeResultFirstVO.setCompanyHoldNo(x.getCscdCrdhlRefno());
composeResultFirstVO.setCardLifeCycle(j.getCardLifeCycle());
composeResultFirstVO.setIssueDate(x.getIssueDate());
composeResultFirstVO.setSaleableProductCode(x.getLgperCode());
return composeResultFirstVO;
}
}