SpringBoot 自定义字典翻译组件

【SpringBoot3】使用Easy-Trans做字典翻译 在项目中经常会有一些根据id从某个表中查name或者从数据字典表中根据code查name的场景。 Easy-Trans 可以非常优雅的实现以上需求,可以有效减少字段冗余。 阅读详情

本来想在项目里直接用Easy-Trans来做字典翻译,用的时候发现,这个组件不支持原生的mybatis.

于是直接自己写了一个。废话不多说,直接上代码。就两个文件。

import java.lang.annotation.*;

/**
 * 字典翻译注解,用于实体类字段自动翻译
 */
@Target(ElementType.FIELD) // 作用于字段
@Retention(RetentionPolicy.RUNTIME) // 运行时生效
@Documented
public @interface DictTrans {
    /** 字典key(对应Redis中的字典类型) */
    String dictKey();

    /** 目标翻译字段名(存储翻译结果的字段) */
    String targetField();
}

我这里是直接从redis中取出来进行字典进行翻译


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.geek.common.constant.CacheConstants;
import com.geek.common.core.redis.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;

/**
 * 字典翻译切面,自动处理@DictTrans注解的字段翻译
 */
@Aspect
@Component
@Slf4j
public class DictTransAspect {

    @Resource
    private RedisCache redisCache;
    /**
     * 切入点:拦截Service层所有返回实体/集合的方法
     * (根据实际工程调整包路径,确保覆盖业务Service)
     */
    @AfterReturning(
            pointcut = "execution(* com.geek.system.service..*(..))", // 拦截system.service包下所有方法
            returning = "result" // 方法返回值
    )
    public void doDictTrans(Object result) {
        if (result == null) return;

        // 处理集合类型(List/Set等)
        if (result instanceof Collection<?>) {
            Collection<?> collection = (Collection<?>) result;
            collection.forEach(this::processEntity);
        } else {
            // 处理单个实体
            processEntity(result);
        }
    }

    /**
     * 处理单个实体对象的字典翻译
     */
    private void processEntity(Object entity) {
        if (entity == null) return;

        Class<?> entityClass = entity.getClass();
        // 获取实体类所有字段(含父类私有字段)
        List<Field> allFields = getAllFields(entityClass);

        for (Field field : allFields) {
            // 检查字段是否标注@DictTrans注解
            DictTrans dictTrans = field.getAnnotation(DictTrans.class);
            if (dictTrans == null) continue;

            try {
                // 1. 获取源字段(编码字段)的值
                field.setAccessible(true); // 允许访问私有字段
                String sourceValue = (String) field.get(entity);
                if (sourceValue == null) continue; // 编码值为null则跳过
                // 2. 从Redis获取JSON数组字符串并解析为映射(修正类型不匹配问题)
                String dictKey = dictTrans.dictKey();
                String redisFullKey = CacheConstants.SYS_DICT_KEY + dictKey;
                // 直接获取JSONArray对象(无需字符串解析)
                JSONArray dictJsonArray = (JSONArray) redisCache.getCacheObject(redisFullKey);
                if (dictJsonArray == null || dictJsonArray.isEmpty()) {
                    log.error("字典翻译失败:Redis中未找到键[{}]或JSON数组为空", redisFullKey);
                    continue;
                }

                // 步骤3:构建dictValue -> dictLabel的映射
                Map<String, String> dictMap = new HashMap<>();
                for (int i = 0; i < dictJsonArray.size(); i++) {
                    JSONObject dictItem = dictJsonArray.getJSONObject(i);
                    String dictValue = dictItem.getString("dictValue");
                    String dictLabel = dictItem.getString("dictLabel");
                    dictMap.put(dictValue, dictLabel);
                }
                // 获取翻译后的值(补充缺失步骤)
                String translatedValue = dictMap.get(sourceValue);
                if (translatedValue == null) {
                    log.warn("字典翻译警告:字典key[{}]中无编码[{}]的映射", dictKey, sourceValue);
                }
                // 4. 反射设置目标字段(翻译结果字段)的值
                String targetFieldName = dictTrans.targetField();
                Field targetField = entityClass.getDeclaredField(targetFieldName);
                targetField.setAccessible(true);
                targetField.set(entity, translatedValue);

            } catch (NoSuchFieldException e) {
                log.error("字典翻译反射异常:目标字段[{}]不存在", dictTrans.targetField(), e);
            } catch (IllegalAccessException e) {
                log.error("字典翻译反射异常:字段访问权限不足", e);
            }
        }
    }

    /**
     * 获取类的所有字段(含父类私有字段)
     */
    private List<Field> getAllFields(Class<?> clazz) {
        List<Field> fields = new ArrayList<>();
        while (clazz != null && clazz != Object.class) { // 遍历至Object类停止
            fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass(); // 处理父类字段
        }
        return fields;
    }
}

使用方式,直接在实体字段上用注解  @DictTrans   

dictKey是对应的字典的key 
targetField是翻译后映射的字段
    @DictTrans(dictKey = "transaction_type", targetField = "transactionTypeName")
    private String transactionType ;
    private String transactionTypeName;

【SpringBoot】24、SpringBoot中实现数据字典 数据字典是指对数据的数据项、数据结构、数据流、数据存储、处理逻辑等进行定义和描述,其目的是对数据流程图中的各个元素做出详细的说明,使用数据字典为简单的建模项目 阅读详情

相关推荐

深入解析Unity3D中PostLateUpdate突然占用大量时间的原因

在Unity3D的生命周期中,是一个在LateUpdate之后被调用的方法。它通常用于处理一些需要在所有更新(包括物理更新和动画更新)之后进行的逻辑。由于它在游戏循环的后期阶段被调用,因此它通常用于处理与渲染直接相关的任务,如相机调整、UI更新等。突然占用大量时间的问题可能由多种原因引起,包括复杂的逻辑处理、频繁的资源加载、不恰当的渲染优化、插件或第三方库的副作用以及内存泄漏或垃圾回收等。为了解决这个问题,开发者需要仔细审查和优化中的代码,同时利用Unity提供的工具来监控和分析游戏性能。

Yori_22的博客 981

springboot 字典翻译

springboot字典翻译

Coco_chun的博客 2097

YOLOv8剪枝实战:基于torch_pruning的模型优化与性能提升指南

本文详细介绍了如何使用torch_pruning工具对YOLOv8模型进行结构化剪枝,以实现模型轻量化与性能提升。通过实战步骤解析,包括环境搭建、依赖图分析、迭代剪枝与微调策略,帮助开发者有效减少模型参数量和计算量,提升在边缘设备上的推理速度,同时保持检测(detect)与分割(segment)任务的精度。

water的专栏 1122

springboot项目 字典/枚举翻译 终极解决方案 AOP+自定义注解+递归实体字段+实体动态三级缓存+责任链+多种转换方式

字典,即在存储介质中进行存储时,为了避免业务上对其名称的调整,所以存储其编码,在进行展示时,将其中文展示出来.我了解到,早期还有中可能是: 存储中文时,有编码问题. 不过我觉得这种说法无法成立,如果面向的用户是中国用户,系统就不可能不存中文.我的这种实现方式,不仅帮组实现了字典翻译的业务, 还用到了设计模式和一些技术,二次拓展方便,值得一学.

ql_7256的博客 2550

Shopee前端反爬三要素:x-sap-Ri、x-sap-Sec与af-ac-enc-dat深度解析

电商前端反爬机制本质是运行时环境可信验证,其核心在于动态生成的请求指纹、会话签名与行为加密载荷。这类机制不依赖静态Token,而是基于浏览器真实交互(如鼠标轨迹、页面可见性、时间精度)实时计算,体现JS运行时环境不可模拟性。技术价值在于将风控前移至客户端,大幅提升自动化绕过成本;典型应用场景包括商品价格监控、竞品数据采集与合规爬虫开发。本文聚焦Shopee实战案例,深入拆解x-sap-Ri(设备+行为哈希指纹)、x-sap-Sec(动态密钥签名)及af-ac-enc-dat(AES加密行为载荷)三大字段的生

weixin_29015127的博客 408

将Python爬取的数据导入钉钉多维表

摘要:本文介绍将Python爬取的数据导入钉钉多维表的完整解决方案。首先通过requests库爬取数据并解析为结构化格式,然后使用钉钉开放平台API对接多维表。关键步骤包括获取app_key、app_secret等凭证,通过OAuth2获取access_token,以及批量写入记录。文章详细说明了参数获取位置、字段类型匹配、权限配置等注意事项,并提供了错误处理建议和性能优化方法。适用于需要将网络数据同步到钉钉多维表的开发场景。

IT深耕十余载,大道之简 2131

SpringBoot自定义注解+AOP处理数据字典自动翻译

在日常开发中系统字典是必不可少的东西,一般业务表里只存储字段的code,但是在查询的时候需要回显字典的Name的值

李大胖 2907

网格聚类 Grid Clustering/Grid-based Clustering

本文主要简单介绍了网格聚类的基本概念,优缺点,应用场景,建模时的注意事项,评价指标,实现方法,python示例和模型参数等。

JasonH2021的博客 4829

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

本文介绍了SpringBoot项目中常见的数据翻译实现方案,主要包括枚举翻译、字典表翻译、SQL查询翻译等多种方式。核心内容包括:1)使用@DictType、@TransEnum、@TransDict等注解定义和实现翻译逻辑;2)通过@TransSQL支持动态SQL查询翻译;3)自定义TransDictHandler处理翻译优先级;4)提供两种翻译调用方式(手动调用和全局自动处理)。同时介绍了数据脱敏注解@JsonSensitive的使用。该方案可有效简化开发中的多数据源翻译需求,支持枚举、数据库表、远程调

mxskymx的专栏 2912

华为OD新系统机试真题-勇攀数字高峰(Java/Py/C/C++/Js/Go)

新系统 华为OD机试新系统【勇登数字高峰】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD新系统机试真题【勇登数字高峰】

qq_45776114的博客 1551

GB28181 —— 3、C++编写GB28181设备端,完成注册、注销、保活心跳、响应查询目录等功能(附源码)

GB28181 —— Win10下编写GB28181设备端,完成注册、注销、保活心跳、响应查询目录等功能(附源码)

1310

SpringBoot字典翻译

SpringBoot字典翻译

wenshuhao888999的博客 888

YOLOv11改进策略【卷积层】| TIP 2025 MFA 多阶段特征聚合 大核扩感受 + 多梯度融合,强效增强弱小目标特征

红外弱小目标尺寸极小、信噪比低,在特征传递中极易丢失信息;常规卷积感受野单一、梯度源不足,难以同时捕捉局部细节与全局上下文,导致小目标特征表达弱、检测漏检。因此提出多阶段特征聚合 MFA,用大核卷积+多分支+通道注意力强化小目标特征提取。

Limiiiing的博客 587

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

字典部分这一块无论是前端和后端都可以做,在目前所接触的项目环境中是前端来做会比较方便的,但是有遇到需要不断远程调用查询的场景,类似的动作不断重复的代码,因此就自己写了个注解实现字典翻译,故此来记录一下过程。环境:SpringBoot+Mybatis-plus很多场景下,我们存储的数据是需要经过翻译的,就比如:这些数据存在系统的字典中,表数据存储的时候为了性能考虑不直接存 男 、 女,只是存1 或 0 ,前台展示的时候就需要把该值进行翻译。每个业务都写的话会比较多类似的操作,可以使用AOP的形式简化工作。一般

小墨鱼的网络博客,不随大流的程序员世界... 2410

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

字典 | springboot 返回数据字典翻译

1.前言 在处理完数据返回前端时,通常需要做字典翻译,此时就需要一个好用的处理工具,但是依然不方便,对此,再次封装了一次。 原理 在接口返回时拦截 --- 反射获取对应字典信息 -- 查询字典值 --- 再次塞入对象里面 --- 返回信息 2.代码 字典类型处理 import java.lang.annotation.*; /** * 字典类型处理 拦截 * <p>常用返回类型处理,不进行四层深层处理</p> * * @author wbw * @d

qq_41497111的博客 4733

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

springboot 数据字典设计思路:字典表+字典枚举 两者兼故方案

springboot 数据字典设计思路:字典表+字典枚举 两者兼故方案,查询返回结果在controller方法上添加注解进行字典翻译

mxskymx的专栏 9619

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

自定义数据字典翻译注解

自定义数据字典翻译注解参考出处代码背景@Dict注解注解对应实现类工具类service层查询接口service实现类和Mybatis的SQL语句实体类缓存的ehcache.xml存放在项目的位置ehcache.xmlehcache.xsd项目位置ehcache.xsd内容每次新增或修改数据字典时候清空当前缓存数据表表格图片:表格数据样例使用样例 参考出处 https://blog.youkuaiyun.com/weixin_42687829/article/details/103289383 代码背景 小公司新项目加上

qq_44754081的博客 3166

java实现应用系统中字典统一翻译组件

字典翻译在我们应用里是一个很正常普遍的需求。 对于小型项目我们可能在数据库设计层面通常不会进行分库处理,那么对于此类项目,通常字典翻译会通过sql语句的子查询来处理,如果业务系统中存在较多的字段为code值时,我们需要编写大量的子查询用于code->name 的代码。在代码层面上造成代码的冗余,在查询数据体量较大的情况并且编写sql人员的能力的不足导致查询性能问题。 对于中大型项目我们可...

F_Hello_World的博客 1826

SpringBoot项目:字典翻译,接口加密,数据脱敏等

在几乎所有SpringBoot项目中都会面临:字典翻译,接口数据加密,数据脱敏的问题。在每个接口中单独的解决会非常繁琐,因此接下来介绍一下怎么通过注解快速解决这些问题。

today_liqiu的博客 1364

SpringBoot集成Easy-Trans数据翻译组件教程

如果需要自定义翻译逻辑,可以实现@Component@Override// 自定义翻译逻辑通过以上步骤,您已经成功在SpringBoot项目中集成了Easy-Trans数据翻译组件。该组件能够显著简化开发过程中常见的数据翻译工作,提高开发效率,同时保持代码的整洁性和可维护性。​​最佳实践建议​合理使用缓存,提高翻译性能统一管理字典数据,确保翻译一致性在微服务架构中,合理规划翻译策略定期监控翻译组件的性能和稳定性。

Rysxt_的博客 1364

SpringBoot整合EasyPoi自定义字典导出Excel

一、简介 可以方便的写出 Excel 导出,Excel 模板导出,Excel 导入,Word 模板导出,通过简单的注解和模板语言(熟悉的表达式语法),完成以前复杂的写法 二、导入依赖 EasyPoi <!-- easypoi --> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-spring-boot-starter</artifactId&g

qq_44691484的博客 1980

【SpringBoot+Mybatis-plus+maven+session拦截器+配置字典项自定义注解】实现简单的用户登录与字段字典项翻译(附源码)

【SpringBoot+Mybatis-plus+maven+session拦截器+配置字典项自定义注解@Dict】实现简单的用户登录与字段字典项翻译(附源码)

qq_42900934的博客 917

SpringBoot 通过自定义注解 + AOP 实现数据字典自动翻译(通用方案)

本文提出了一种基于SpringBoot的自定义注解+AOP数据字典自动翻译方案。通过定义@Dict注解标记需要翻译的字段,结合AOP切面技术实现自动字典转换。该方案支持多种返回类型(分页、列表、单对象)、递归嵌套翻译、多值处理和Redis缓存,并通过抽象DictDataProvider接口实现多项目复用。核心流程包括:注解解析、数据加载、缓存处理和结果追加,最终在原始字段后补充_dictStr字段返回翻译结果,兼顾前端展示和筛选需求。该方案具有低侵入性、高可配置性和良好的扩展性,有效解决了企业开发中字典翻译

qq_42945407的博客 221

springboot通过aop实现自定义字典翻译注解

【代码】springboot通过aop实现自定义字典翻译注解。

cdicon的博客 1038

SpringBoot 数据翻译组件-easy_trans

简介 开发中会经常遇到这样的场景:比如在成绩表有一个student_id,如果我要查看成绩列表需要学生的名称,一般写法就是使用join,现在大部分ORM框架对于表关联支持并不是很友好,所以很多时候我们都要自己写SQL去实现。 翻译服务即:通过id,将对应的title/name 字段翻译出,装载到VO中用于前端展示的技术. 1 FHS 提供的翻译服务如何使用? a ...

陕西小伙伴网络科技有限公司-技术博客 5754
上一篇: Springboot 集成graalvm.js 执行JavaScript
下一篇: Java 设计模式(介绍)
Java程序之猿
博客等级 码龄9年 2599粉丝 140原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值