springboot之数据翻译组件:支持枚举、字典表、外键翻译、对象翻译、属性脱敏

本文介绍了在SpringBoot项目中如何进行数据翻译,包括枚举、字典表、外键等的处理方法,通过注解@TransEnum、@TransDict、@TransSQL和@TransClass实现自动化翻译,并给出了依赖引入和源代码链接。

 

1. 数据翻译

        springboot 项目开发中常见到的数据翻译包括:

        枚举翻译、字典表翻译、外键翻译、字段翻译、对象翻译、属性脱敏等。

 

2. 数据来源

  • 枚举代码(枚举)
  • 数据表(字典表、关联表)
  • 自定义方法(本地处理,跨服务查询、第三方API查询等)

核心注解

应用场景

@DictType

@DictType(value = "sys_is_used", label = "使用状态")

说明:枚举字典定义标识

@TransEnum

@TransEnum(dictType = "类型code", source = "变量名")

说明:使用枚举翻译

@TransDict

@TransDict(dictType = "类型code", source = "源变量名")

说明:优先使用枚举翻译,再使用字典表翻译;

需要自定义实现接口 TransDictHandler,用于读取字典表翻译

@TransSQL

@TransSQL(value = "select xx from xx where id=#{变量名}")

说明:动态sql翻译,支持常用类型和对象

 

@TransSQL(sqlIdInMapper = "selectXxx")

说明:动态sql太长,可以放在Mapper.xml中,<sql id="selectXxx">select ....</sql>

sqlIdInMapper要求唯一,可以放在任意Mapper.xml中,动态条件使用 [and id=#{id}]

@TransTable

@TransTable(table="t_tenant", foreignKey = "tenant_id")

说明:表外键翻译,支持常用类型和对象

@JsonSensitive

@JsonSensitive(strategy = SensitiveStrategy.PASSWORD)

@JsonSensitive(strategy = SensitiveStrategy.PHONE)

说明:属性脱敏显示

 

3. 使用介绍

引入maven 依赖方式:将 jar 放在/libs目录下,配置如下

<dependency>
    <groupId>com.geline.cloud</groupId>
    <artifactId>cloud-coder-starter-easytrans</artifactId>
    <scope>system</scope>
    <version>1.3.4</version>
    <systemPath>${project.basedir}/libs/cloud-coder-starter-easytrans-1.3.4.jar</systemPath> 
</dependency>

自定义 TransDictHandler 实现类

/**
 * 自定义翻译: 优先使用枚举翻译,找不到再使用表字典翻译
 */
@Component
public class MyTransDictHandler implements TransDictHandler {

    @Resource
    private DictEnumRegistry dictEnumRegistry;
    @Resource
    private SysDictDataMapper sysDictDataMapper;

    @Override
    public String getDictLabel(String dictType, Object dictValue) {
        String dictLabel = this.dictEnumRegistry.getDictLabel(dictType, dictValue);
        if(dictLabel != null) {
            return dictLabel;
        }
        return sysDictDataMapper.selectDictLabel(dictType, String.valueOf(dictValue));
    }

    @Override
    public Object getDictValue(String dictType, String dictLabel) {
        Object dictValue = this.dictEnumRegistry.getDictValue(dictType, dictLabel);
        if(dictValue != null) {
            return dictValue;
        }
        return sysDictDataMapper.selectDictValue(dictType, dictLabel);
    }
}


/**
 * 字典翻译查询
 */
@Mapper
public interface SysDictDataMapper extends BaseMapper<SysDictData> {

    //根据字典类型和字典值查询字典标签
    @Select("select dict_label from sys_dict_data where dict_type = #{dictType} and dict_value = #{dictValue}")
    String selectDictLabel(String dictType, String dictValue);

    //根据字典类型和字典标签查询字典值
    @Select("select dict_value from sys_dict_data where dict_type = #{dictType} and dict_label = #{dictLabel}")
    String selectDictValue(String dictType, String dictLabel);
}


@DictType:自定义一个枚举字典类

import com.geline.easytrans.annotation.DictType;
import com.geline.easytrans.dict.IDict;
import lombok.AllArgsConstructor;
import lombok.Getter;


@DictType(value = "sys_is_used", label = "使用状态")
@AllArgsConstructor
@Getter
public enum IsUsedEnum implements IDict {
    Y("Y", "正常"),
    N("N", "未使用"),
    D("D", "已删除");

    private String code;
    private String desc;

    @Override
    public String getLabel() {
        return desc;
    }

    @Override
    public Object getValue() {
        return code;
    }
}

@TransEnum:使用枚举字典翻译

@Getter
@Setter
public class ProjectDTO implements Serializable {
    
    /* 应用状态:字典值 */
    private String status;
    
    /* 应用状态:字典名称  */
    @TransEnum(dictType = "project_status", orgFieldName = "status")
    private String statusDesc;

    /* 业务类型 sys_oper_type */
    private String operType;

    @TransDict(dictType = "sys_oper_type", source = "operType")
    private String operTypeDesc;
}


//定义一个枚举
@DictType(value = "project_status", label = "应用状态")
public enum ProjectStatusEnum implements IDict {
    no("未开始"), 
    go("开发中"), 
    check("验收中"), 
    over("完成");

    private String label;

    ProjectStatusEnum(String label){
        this.label = label;
    }

    @Override
    public String getLabel() {
        return label;
    }

    @Override
    public Object getValue() {
        return name();
    }
}

@TransSQL:支持sql翻译,参数selectSql可以引用动态变量 #{userName},  ${userId}

@Getter
@Setter
public class ProjectDTO implements Serializable {

    private String userId;

    @TransSQL(selectSql = "select user_name from sys_user where id=#{userId}")
    private String userName;

    private String dataBaseId;

    @TransSQL(value = "select * from sdk_data_base where id=#{dataBaseId}")
    private DataBase dataBase;

    @TransSQL("select *from sdk_data_base where id=#{dataBaseId}")
    private List<DataBase> codeList;

    private String saleId;

    @ApiModelProperty(value = "其它费用")
    @TransSQL(sqlIdInMapper = "selectOtherPriceBySale")
    private BigDecimal otherPrice;
}



>>>> SaleDetailMapper.xml添加代码 <<<<

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.geline.order.mapper.SaleDetailMapper">
    <sql id="selectOtherPriceBySale">
        select sum(os.curr_share_amount) as otherPrice
        from t_finance_other_source os
        left join t_finance_other o on o.id=os.finance_other_id
        left join t_expenses e on o.expenses_id=e.id
        where o.order_status in('PART', 'UNPAID', 'PAID') and e.expenses_code not in('sale_wlyf') and os.source_id=#{saleId}
    </sql>
    ....
</mapper>

 

翻译方式一:手动调用

@RestController
@RequestMapping("/project")
@Slf4j
public class ProjectController {

    @Autowired
    private ProjectService projectService;
    @Autowired
    private EasyTransService transService;

    /**
     * Get  localhost:9501/project/listByGroup/{groupId}
     * @param groupId
     * @return
     */
    @ApiOperation(value = "查询应用列表(分组下)")
    @GetMapping("/listByGroup/{groupId}")
    public Result listByGroup(@PathVariable String groupId) {
        List<ProjectDTO> list = this.projectService.listByGroup(groupId);
        //翻译属性
        transService.transBatch(list);
        return Result.ok(list);
    }
}

翻译方式二:全局自动翻译

/**
 * 返回结果处理
 * 处理字典翻译 @TransEnum, @TransSQL, @TransTable
 */
@RestControllerAdvice
@Slf4j
public class ResultBodyAdvice implements ResponseBodyAdvice {

    @Autowired
    protected EasyTransService easyTransService;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        Class<?> parameterType = returnType.getParameterType();
        return parameterType == Result.class || parameterType == TableDataInfo.class;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if(body instanceof Result){
            Result bean = (Result)body;
            if(bean.getCode()==0){
                Object data = bean.getData();
                if(data!=null){
                    if(data instanceof List){
                        easyTransService.transBatch((List) data);
                    }else {
                        easyTransService.transOne(data);
                    }
                }
            }
        }else if(body instanceof TableDataInfo){
            TableDataInfo bean = (TableDataInfo)body;
            if(bean.getCode()==0){
                List<?> rows = bean.getRows();
                if(rows!=null){
                    easyTransService.transBatch(rows);
                }
            }
        }
        return body;
    }
}

源代码地址:cloud-coder-starter: java基础组件沉淀 - Gitee.com

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI产品实战

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值