自定义注解绑定字典

一般情况下数据库表中存储的字段是其所对应的字典值,但当我们更据id查询详情或者查询列表时,每次都需要关联字典表查询,这样比较繁琐。
所需依赖:hutool 及 AOP

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!--hutool-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.5</version>
        </dependency>

1.新建字典表

在这里插入图片描述

2.自定义注解

/**
 * @author ntxz
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindDict {

    //绑定的字段映射
    String filedMapping();

    //字典类型
    String type();
} 

3.编写注解aop实现

import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ntxz.functional.entity.Result;
import com.ntxz.functional.entity.SysDict;
import com.ntxz.functional.service.SysDictService;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * @author ntxz
 * @create 2023-02-20-14:36
 */
@Aspect
@Component
@Slf4j
public class DictAop {

    @Autowired
    private SysDictService sysDictService;



    //切入点 com.ntxz.functional包下所有 类名是 *Controller 的类,方法参数任意个。
    @Pointcut("execution(* com.ntxz.functional..*.*Controller.*(..))")
    public void around()
    {
    }

    /*
     * 环绕通知
     * */
    @Around("around()")
    public Object process(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        //1.执行原方法
        Object proceed = proceedingJoinPoint.proceed();
        //2.拿到原方法的原返回值 调用parseDict进行字典转换
        this.parseDict(proceed);
        return proceed;
    }

    
    private void parseDict(Object result) throws IllegalAccessException {

        // 1.检测是否为统一返回(更据自身情况修改,Result是我自己编写的一个统一返回)
        if(result instanceof Result){
            //2.获取Result中的数据体
            Object metaObj = ((Result) result).getData();
            
            //返回是否是列表
            if (metaObj instanceof ArrayList){
                ArrayList list = (ArrayList) metaObj;
                for (Object a:list){
                    doParseDict(a);
                }
            }
            //返回单个对象
            if (metaObj != null && !(metaObj instanceof ArrayList) ){
                doParseDict(metaObj);
            }

        }
    }
    //绑定字典
    public void doParseDict(Object obj) throws IllegalAccessException {
        Field[] fields = ReflectUtil.getFields(obj.getClass());
        if (fields != null && fields.length != 0){
            Iterator<Field> iterator = Arrays.stream(fields).iterator();
            while (iterator.hasNext()){
                Field field = iterator.next();
                BindDict dict = field.getAnnotation(BindDict.class);
                //获取绑定了注解的字段
                if (dict !=null){
                    //设置取消字段保护
                    field.setAccessible(true);
                    String mapping = dict.filedMapping();//字典值所在字段名
                    Field mappingField = ReflectUtil.getField(obj.getClass(), mapping);//获取字典值所在字段
                    mappingField.setAccessible(true);

                    //查询字典表
                    QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("type",dict.type()).eq("item_value",mappingField.get(obj));
                    SysDict dict1 = sysDictService.getOne(queryWrapper);
                    field.set(obj,dict1.getItemName());//设置字典
                }
            }
        }
    }

}

4.字典实体类

@TableName(value ="sys_dict")
@Data
public class SysDict implements Serializable {
    /**
     * 
     */
    @TableId(type = IdType.AUTO)
    private Integer id;

    /**
     * 字典类型
     */
    private String type;

    /**
     * 字典值
     */
    private String itemValue;

    /**
     * 字典名称
     */
    private String itemName;

    @TableLogic
    private String isDeleted;

    private Date createTime;
    
    private Date updateTime;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

5.统一返回Result


/**
 * @author ntxz 
 * @create 2021-10-19-22:27
 */
 @Data
public class Result<T> {
    //响应状态码
    private Integer code;
    //响应信息
    private String msg;
    //总记录数
    private Long count;
    //代表返回的数据
    private T data;
}

6.测试类及vo用于绑定注解(也可以直接在实体类中使用)

测试类

@Data
public class TestDict {
    @TableId(type = IdType.AUTO)
    private Integer id;

    private String name;

    private String address;

    private String sex;

}

vo

@Data
@ToString(callSuper = true)
public class TestDictVo extends TestDict {

    @BindDict(filedMapping = "sex",type = "sex") //filedMapping 对应实体类的哪个字段,type字典类型
    private String sexName;

    @BindDict(filedMapping = "address",type = "address")
    private String addressName;
    
 	@BindDict(filedMapping = "auditCode" ,type = "audit")
    private String auditName;

}

7.编写测试Crontroller

@RestController
@Slf4j
@RequestMapping("/API")
public class APIController {

    @GetMapping("/detail")
    public Result getDict(){
        TestDictVo testDictVo=new TestDictVo();
        TestDict testDict = new TestDict();
        testDict.setId(0);
        testDict.setAddress("0");
        testDict.setSex("0");
        testDict.setName("sfgs");
        BeanUtils.copyProperties(testDict, testDictVo);
        return ResultUtils.buildSuccess(testDictVo);
    }
    
    @GetMapping("/list")
    public Result getDict1(){
        TestDictVo testDictVo=new TestDictVo();
        TestDictVo testDictVo2=new TestDictVo();
        TestDict testDict = new TestDict();
        testDict.setId(0);
        testDict.setAddress("0");
        testDict.setSex("0");
        testDict.setName("sfgs");

        TestDict testDict2 = new TestDict();
        testDict2.setId(1);
        testDict2.setAddress("2");
        testDict2.setSex("1");
        testDict2.setName("sdfffg");
		
        BeanUtils.copyProperties(testDict, testDictVo);
        BeanUtils.copyProperties(testDict2, testDictVo2);
        ArrayList<TestDictVo> list = new ArrayList<>();
        list.add(testDictVo2);
        list.add(testDictVo);
        return ResultUtils.buildSuccess(list);
    }
}

detail测试:

在这里插入图片描述

list测试:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值