河南省两学一做网站,域名访问wordpress,网站模板名称,网站改版销售话术需求#xff1a; 有时候我们在查询mapper层时#xff0c;有时候可能由于入参数据过大或者查询的范围较大#xff0c;导致查询性能较慢#xff0c;此时 我们需要将原本的查询按照一定规则将查询范围进行切面#xff0c;然后分片查询#xff0c;最后将查询结果进行组装合并…需求 有时候我们在查询mapper层时有时候可能由于入参数据过大或者查询的范围较大导致查询性能较慢此时 我们需要将原本的查询按照一定规则将查询范围进行切面然后分片查询最后将查询结果进行组装合并 1自定义注解 import com.taia.yms.aop.reponse.inter.MapperRequestSlicesInterface;
import java.lang.annotation.*;/*** 主要针对 查询 mapper 时使用一定规则进行切片后按照指定并发个数进行mapper查询然后再汇总结果*/
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
Documented
Inherited
public interface MapperRequestSlices {/*** 指定执行规则的方法默认方法为asyncExecute* return*/String method() default asyncRequestExecute;Class? extends MapperRequestSlicesInterface operation();
}
2定义切片规则接口 /*** 主要针对mapper层查询需要按照自定义规则 进行分片并发查询提升效率* param T*/
public interface MapperRequestSlicesInterfaceR,T {R asyncRequestExecute(Object request);}
3编写核心切面处理类 import com.taia.yms.aop.reponse.inter.MapperRequestSlicesInterface;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;Component
Aspect
Slf4j
public class MapperRequestSlicesAspect {Pointcut(execution(* com.taia.yms.mapper.*.*(..)) annotation(com.taia.yms.aop.reponse.MapperRequestSlices))private void pointCut() {//方法为空仅做签名}//对切点方法进行前置增强就是在调用切点方法前进行做一些必要的操作这就成为增强Around(pointCut())public Object getRes(ProceedingJoinPoint joinPoint) throws Throwable {// 获取被拦截的方法签名MethodSignature signature (MethodSignature) joinPoint.getSignature();// 获取被拦截的方法Method method signature.getMethod();Object[] objects joinPoint.getArgs();Object target joinPoint.getTarget();Class? returnType method.getReturnType();//针对 返回值是集合的场景便于后期切片后汇总if(!returnType.getTypeName().equalsIgnoreCase(List.class.getTypeName())){return joinPoint.proceed();}MapperRequestSlices annotation method.getAnnotation(MapperRequestSlices.class);// 查找并获取注解try{// 读取注解的属性Class? extends MapperRequestSlicesInterface operation annotation.operation();MapperRequestSlicesInterface operationInstance operation.getDeclaredConstructor().newInstance();String methoded annotation.method();Method operationMethod operation.getDeclaredMethod(methoded, Object.class);Object obj operationMethod.invoke(operationInstance, objects);//如果切分的结果只有一个那么还是按照原有的查询来if(!(obj instanceof List obj ! null)){return joinPoint.proceed();}ListObject result ((List?) obj).stream().flatMap(v - {try {return ((ListObject)(method.invoke(target, v))).stream();} catch (Exception e) {log.error(类[{}]的方法[{}]执行失败报错:{},target.getClass().getName(),method.getName(),e.getMessage());throw new RuntimeException(e);}}).collect(Collectors.toList());return result;}catch (Throwable e){log.error(类[{}]的方法[{}]执行失败报错:{},annotation.operation().getName(),annotation.method(),e.getMessage());return joinPoint.proceed();}}}
4编写切片规则实现类 import com.taia.yms.aop.reponse.inter.MapperRequestSlicesInterface;
import com.taia.yms.entity.po.QualityViewPo;
import com.taia.yms.entity.requestbody.SummarySearchRequestBody;
import com.taia.yms.entity.vo.DataTypeSlice;
import com.taia.yms.entity.vo.DataTypeVo;
import com.taia.yms.enums.RangeTypeEnum;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.stream.Collectors;public class DataByTime2ReqSlice implements MapperRequestSlicesInterfaceListSummarySearchRequestBody,ListQualityViewPo {Overridepublic ListSummarySearchRequestBody asyncRequestExecute(Object request) {if(request null){return null;}SummarySearchRequestBody requestBody (SummarySearchRequestBody) request;//按 天统计不考虑if(RangeTypeEnum.DAY.getType().equalsIgnoreCase(requestBody.getRangeType())){return null;}DataTypeVo dataTypeVo requestBody.getDataTypeVo();if(dataTypeVo null || CollectionUtils.isEmpty(dataTypeVo.getDataTypeSliceList())){return null;}ListDataTypeSlice dataTypeSliceList dataTypeVo.getDataTypeSliceList();dataTypeSliceList.stream().sorted();ListSummarySearchRequestBody bodyList dataTypeSliceList.stream().map(v - {SummarySearchRequestBody summarySearchRequestBody new SummarySearchRequestBody();BeanUtils.copyProperties(requestBody, summarySearchRequestBody);summarySearchRequestBody.setStartDate(v.getStartTime());summarySearchRequestBody.setEndDate(v.getEndTime());return summarySearchRequestBody;}).collect(Collectors.toList());return bodyList;}}
5编写相关对象类 import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;/*** ClassName QualityViewPo* Date 2023/4/25 11:47* Version 1.0**/
Data
AllArgsConstructor
NoArgsConstructor
Accessors(chain true)
public class QualityViewPo {private Integer countNum;private String dateTime;private Integer successFilesNum;private Integer failFilesNum;private Integer loadingFilesNum;private Integer qualityScore;private String fabProductVersion;private String station;
} import com.taia.yms.entity.ExportPageReqBody;
import com.taia.yms.entity.vo.DataTypeVo;
import com.taia.yms.validgroups.summarysearch.DataProgressSummaryGroup;
import com.taia.yms.validgroups.summarysearch.TodayBoardGroup;
import com.taia.yms.validgroups.summarysearch.TrendsBoardGroup;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.sql.Timestamp;
import java.util.List;Data
AllArgsConstructor
NoArgsConstructor
Accessors(chain true)
public class SummarySearchRequestBody extends ExportPageReqBody {/**时间区间 day/week/month*/ValidNotEmpty(message 时间范围为空, groups {DataProgressSummaryGroup.class, TrendsBoardGroup.class})Pattern(regexp day|week|month|custom|year|all,message 时间范围不符合正则, groups {DataProgressSummaryGroup.class, TrendsBoardGroup.class})private String rangeType;/**开始时间*/NotNull(message 开始时间为空, groups {DataProgressSummaryGroup.class, TrendsBoardGroup.class})private Timestamp startDate;/**结束时间*/NotNull(message 结束时间为空, groups {DataProgressSummaryGroup.class, TrendsBoardGroup.class})private Timestamp endDate;/**数据类型 WAT/INLINE/CP-BIN/DEFECT*/ValidNotNull(message 数据类型为空, groups {DataProgressSummaryGroup.class, TodayBoardGroup.class, TrendsBoardGroup.class})private ListNotEmpty(message 数据类型为空, groups {DataProgressSummaryGroup.class, TodayBoardGroup.class, TrendsBoardGroup.class}) String stations;/**产品数据 *///NotNull(message 产品数据为空, groups {DataProgressSummaryGroup.class, TodayBoardGroup.class, TrendsBoardGroup.class})private ListString fabProductVersions;private DataTypeVo dataTypeVo;
} import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.List;/*** ClassName ExportPageReqBody* 导出 和 分页数据**/
Data
AllArgsConstructor
NoArgsConstructor
Accessors(chain true)
public class ExportPageReqBody {/**页码*/ApiModelProperty(example 1)private Integer pageNum 1;/**页面大小*/ApiModelProperty(example 10)private Integer pageSize 10;/**1-导出excel 0-导出CSV*/private String isExcel;/**1-只导出表头0或空-导出表头和数据*/private String isEmpty;/**1-配置数据 0或空-待添加配置数据*/private String isConfig;/**选择导出有值时只导出选中的id*/private ListLong selectedIds;/**当前登录用户的userId*/private String userNo;
} import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.List;Data
AllArgsConstructor
NoArgsConstructor
Accessors(chain true)
public class DataTypeVo {private ListString timeTable;private ListDataTypeSlice dataTypeSliceList;} import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.sql.Timestamp;Data
AllArgsConstructor
NoArgsConstructor
Accessors(chain true)
public class DataTypeSlice {private Timestamp startTime;private Timestamp endTime;
}