AOP+自定义注解实现字典翻译

2022-11-20 13:56:27

目录

需求:

结果展示 :

代码实现 :


需求:

        一般情况下数据库表中字段对应的是字典值,但在查询或导出时需要展示字典名,若每次字典转换时都需要关联字典表查询,而且导出时还需要在做一次数据转换,这样处理比较繁琐,会存在冗余代码,不太合理,所以使用AOP自定义注解实现自动翻译。

结果展示 :

  • 导出:

  • 查询:

代码实现 :

  • 新建自定义注解
/**
 * @describe 编码值集
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DictMeaning {

    String code() default "";

    //转换后赋值到绑定字段
    String targetField() default "";
}
  • 新建拦截注解,用于方法上
/**
 * @describe 返回数据处理
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ProcessResult {
}
  • 拦截目标方法
public interface BankTestMapper {

    /**
     * 查询、导出数据
     *
     * @param BankTestVO
     * @return
     */
    @ProcessResult
    List<BankTest> queryList(BankTestVO bankTestVO);

}
  • 新建AOP切面类
/**
 * @describe 编码值集转换
 */
@Slf4j
@Aspect
@Component
public class DictAspect {

    @Autowired
    private DictCodeService dictCodeService;

    // 拦截@processResult标注的方法
    @AfterReturning(value = "@annotation(processResult)", returning = "result")
    public Object enumValue(JoinPoint joinPoint, ProcessResult processResult, Object result) {
        if (Objects.isNull(result)) {
            return null;
        }
        // 校验返回类型list
        if (result instanceof List) {
            List list = (List) result;
            for (Object object : list) {
                convertDictValue(object, object.getClass());
            }
            return result;
        }
        convertDictValue(result, result.getClass());
        return result;
    }

    /**
     * 通过反射获取Bean字段,拦截所使用@Dict注解字段进行数据转换值
     *
     * @param object   对象
     * @param objClass 对象类
     */
    private void convertDictValue(Object object, Class objClass) {
        // 获取当前对象的所有字段
        Field[] fields = objClass.getDeclaredFields();
        if (fields.length == 0) {
            return;
        }
        // 遍历字段上是否有自定义注解
        for (Field field : fields) {
            try {
                // 设置可以访问私有变量的值
                field.setAccessible(true);
                // 字段为空,不执行后续操作
                if (Objects.isNull(field.get(object))) {
                    continue;
                }
                // 解析自定义注解
                DictMeaning annotation = field.getAnnotation(DictMeaning.class);
                if (annotation == null) {
                    continue;
                }
                // 根据值集编码获取 value 含义
                String valueMeaning = getValueMeaning(annotation.code());
                if (StringUtils.isEmpty(valueMeaning)) {
                    continue;
                }
                // 编辑自定义字段
                String setMethodName = null;
                if (StringUtils.isNotEmpty(annotation.targetField())) {
                    // 驼峰命名
                    setMethodName = "set" + annotation.targetField().substring(0, 1).toUpperCase() + annotation.targetField().substring(1);
                }
                // set自定义字段
                Method method = object.getClass().getMethod(setMethodName, String.class);
                if (Objects.isNull(method)) {
                    continue;
                }
                method.invoke(object, valueMeaning);
            } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        // 递归获取父类的属性
        convertDictValue(object, objClass.getSuperclass());
    }

    /**
     * 根据值集编码获取 value 含义
     *
     * @param code
     * @return
     */
    private String getValueMeaning(String code) {
        // TODO 先查询数据表,后续值集数据存入 Redis
        String textValue = dictCodeService.getValueByCode(code);
        if (StringUtils.isEmpty(textValue)) {
            return null;
        }
        return textValue;
    }
}
  • 实体引用注解
/**
 * 实体类
 */
@Data
@TableName("bank_test")
public class BankTest {

    @TableId(value = "id", type = IdType.INPUT)
    @ApiModelProperty(value = "id")
    private Long id;

    @ApiModelProperty(value = "实体名称")
    @ExcelProperty("实体名称")
    private String name;

    @ApiModelProperty(value = "系统编码")
    @ExcelProperty("系统编码")
    private String sysCode;

    @ApiModelProperty(value = "状态", hidden = true)
    @ExcelIgnore
    @DictMeaning(code = "字典编码", targetField = "stateMeaning")
    private Integer state;

    @ApiModelProperty(value = "状态含义", hidden = true)
    @ExcelProperty("状态")
    @TableField(exist = false)
    private String stateMeaning;
}
  • 作者:`倔强男孩`
  • 原文链接:https://blog.csdn.net/weixin_42151235/article/details/121162306
    更新时间:2022-11-20 13:56:27