前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >页面多查询条件必选的统一处理思路

页面多查询条件必选的统一处理思路

原创
作者头像
青衫染红尘
发布2022-11-09 14:57:40
9750
发布2022-11-09 14:57:40
举报
文章被收录于专栏:Surpass' BlogSurpass' Blog

背景

开发中我们可能会遇到会页面对应的数据表量级较大、页面查询条件过多的情况,那么有时候我们可能会限制做查询操作是必须选择至少一个查询条件。

页面效果:

直接查询会提示:

正文

思路

我们考虑使用注解+切面的形式来实现,用来确定哪些方法、哪些参数是需要做筛选和判断的。

注解类:用来标识某个参数和某个类的切入点

代码语言:java
复制
/**
 * 用来标识某个参数和某个类的切入点
 * @author zhouli
 * @Classname ConditionLimitAspect
 * @Date 2022/4/6 19:39
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.METHOD})
public @interface ConditionLimit {
    /**
     * 限制条件最少个数
     *
     * @return
     */
    int conditionNumberLimit() default 1;
}

/**
 * 用来标识哪些字段用来统计查询列
 * @author zhouli
 * @Classname ConditionLimitAspect
 * @Date 2022/4/6 19:39
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ConditionField {
}

切面类:

代码语言:java
复制
@Slf4j
@Aspect
@Component
public class ConditionLimitAspect {
    @Around("execution(* com.p4.tp.system.modules.*.rest.*.*(..,@com.p4.tp.system.config.aop.ConditionLimit (*),..))")
    public Object doCheckCondition(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            //多个参数时循环
            ConditionLimit annotation = parameters[i].getAnnotation(ConditionLimit.class);
            if (annotation == null) {
                continue;
            }
            //设定的最小查询列数量
            int numberLimit = annotation.conditionNumberLimit();
            Object[] args = point.getArgs();
            Class<?> aClass =args[i].getClass();
            Field[] declaredFields = aClass.getDeclaredFields();
            //查询条件计数
            int realNum = 0;
            for (Field field : declaredFields) {
                //获取带ConditionField注解的字段
                ConditionField conditionField = field.getAnnotation(ConditionField.class);
                if (conditionField == null) {
                    continue;
                }
                field.setAccessible(true);
                //获取列值
                Object value = field.get(args[i]);
                if (value == null) {
                    continue;
                }
                try {
                    //列举三种情况
                    if (value instanceof String && StringUtils.isNotBlank((String) value)) {
                        realNum++;
                    } else if (value instanceof Collection && !CollectionUtils.isEmpty((Collection<?>) value)) {
                            realNum++;
                    } else if (value instanceof Date) {
                            realNum++;
                    }
                } catch (Exception e) {
                    log.error("条件限定异常,", e);
                }
            }
            if (realNum < numberLimit) {
                log.info("查询条件不足,请至少选择或输入" + numberLimit + "个查询条件");
                throw new BusinessException("查询条件不足,请至少选择或输入" + numberLimit + "个查询条件");
            }
        }
        return point.proceed();
    }
}

使用

创建实体

代码语言:java
复制
@Data
public class FlowCardInfoParam {

    @ConditionField
    private String iccId;

    @ConditionField
    private String termSn;

    @ConditionField
    private String imei;
}

方法使用

代码语言:java
复制
	@PostMapping("/getPage")
    public ResponseEntity<Object> getPage(@RequestBody @ConditionLimit FlowCardInfoParam param) {
        return new ResponseEntity<>(null, HttpStatus.OK);
    }

现在我们使用接口请求

第一次不填写参数值:{} ,查看日志结果:

第二次填写 iccId 值重新请求: {"iccId":"898604B11921D0192003"},我们就能看到直接放过进行正常的业务调用了。

尾言

以上便是实现多查询条件中必选至少一种字段值的一种思路,正常情况下我们没有必要也没有办法枚举出所有页面中出现的所有必要的查询条件,那么就可以考虑做找一个前置的统一处理方法。利用切面在进入方法前就进行判断,该次请求是否符合接口最低的要求。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 正文
    • 思路
      • 使用
      • 尾言
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档