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

devtools/2024/9/24 9:29:54/

目录

  • 前言
  • 实现思路
    • 技术确定
  • 食用方式
    • 效果
    • 使用样例
    • 项目中使用
      • 第一步 复制包
      • 第二步 实现LoadDictDatabase并将其注入容器
      • 第三步 标识需要翻译的字段
      • 第四步 标识需要翻译的方法
      • 第五步 调用需要翻译的方法
  • 实现细节
  • TODO

前言

字典,即在存储介质中进行存储时,为了避免业务上对其名称的调整,所以存储其编码,在进行展示时,将其中文展示出来.我了解到,早期还有中可能是: 存储中文时,有编码问题. 不过我觉得这种说法无法成立,如果面向的用户是中国用户,系统就不可能不存中文.

我的这种实现方式,不仅帮组实现了字典翻译的业务, 还用到了设计模式和一些技术,二次拓展方便,值得一学.

实现思路

技术确定

在展示时,将字典翻译成显示值,那什么时候翻译呢? 有一种说法是将字典对应的编码返回到前端,让前端展示的时候再翻译. 但是这样我想到了两个问题

  1. 后端在业务上中有可能也需要使用中文名称的, 比如生成文件,根据业务信息生成Word文件、PDF文件等等
  2. 字典的缓存处理,前端如何存储系统的字典,如何刷新缓存呢?我对前端不太了解,但是后端显而易见的处理方式是用redis

在我一步一步的尝试和完善下,最终落地的方案是:

  • 后端翻译

  • AOP+自定义注解: 精确指定需要翻译的字段和方法

  • 动态三级缓存: 模拟经典的 '高速缓存-内存-硬盘’三级缓存,实现了’内存-redis-数据库’三级缓存链,并且redis不是必须的,可以根据项目中是否引入,来动态的组装缓存链.当redis未使用时,会自动组装成’内存-数据库’两层缓存链

  • 多种转换方式: 有三种: 指定数据库(或redis或程序内存)中的字典、指定程序中已有的枚举类、手动指定

  • 责任链: 在这小小枚举翻译中,有两处用到了责任链: 命中的缓存和翻译的方式

    • 命中的缓存: 根据缓存链构建的顺序,如果当前级别命中不到,会丢给下一级缓存,如果在下一级找到了,还会缓存到本级. 下一级的处理逻辑也是如此,直到找到了缓存, 或者全都没找到缓存,返回源字典编码

食用方式

效果

先上效果图,在实体上配置如下
三种翻译方式
最后翻译出的结果如下
翻译结果

使用样例

源码地址: gitee源码

源码中的spring-ordinary项目,有字典翻译的源码和使用样例,
字典源码: com.ql.ordinary.common.dict包中
使用样例: com.ql.ordinary.rest.DictConvertTestController

如果需要需要查看样例效果,需要以下步骤

  • 拉取源代码
  • 更改配置文件中的mysql配置和redis配置
  • 在mysql指定的库中执行spring-ordinary/db/sys-dict.sql脚本
  • 启动服务
  • 调用接口: http://localhost:6660/dict/convert/student/list

如果以上步骤都能成功,那么将看到效果图的的样子

项目中使用

在自己项目中使用,需要如下步骤

第一步 复制包

拉取源代码并复制包. 源码地址: gitee源码

现在只有一种使用方式: 将 com.ql.ordinary.common.dict整个包中的类复制到自己的项目中, 后续会考虑做成starter或者放到maven公共仓库中
如果没有使用redis,

  • 删除项目中引用的redis相关类
  • 取消RedisDictCache的注入

第二步 实现LoadDictDatabase并将其注入容器

com.ql.ordinary.common.dict.service.LoadDictDatabase接口中定义了从数据库中获取字典的方法, 不关心你是怎么从数据库中获取, 也不关心是从什么数据库中获取的. 只需要通过这个接口获取结果

第三步 标识需要翻译的字段

Dict 注解用来标识需要翻译的字段,有多种翻译方式. 详见类上的注释

第四步 标识需要翻译的方法

DictMethod注解用来标识需要翻译的方法,如果没有标识方法,只标识字段,也是没用的.

第五步 调用需要翻译的方法

调用被DictMethod标识的方法,拿到的结果就是被翻译了的结果

实现细节

待补充

TODO

  1. 做成一个starter或者放到公共的maven仓库中
  2. 支持对map的翻译,

http://www.ppmy.cn/devtools/33857.html

相关文章

[408计算机组成原理] 第五章 中央处理器 5.1

🚀 【考纲要求】CPU的功能和基本结构 一、CPU的功能和基本结构 1.1 CPU的功能 要想研究CPU的结构,首先我们应该明确CPU要实现哪些功能,对于CPU首先就应该实现数据算数运行和逻辑运行,同时可以进行取指令,分析指令&am…

CST电磁仿真软件优化器和选择激励的使用【图文教程】

选择激励 各端口的Amplitude、Phase设置和Excitation Type Simulation > Setup Solver > Stimulation Settings CST软件不使用已经定义好的全部Port,只希望使用特定Port进行仿真时,可以在Excitation List中进行设置。 设置方法如下: Stimulati…

【Web】CTFSHOW 中期测评刷题记录(1)

目录 web486 web487 web488 web489 web490 web491 web492 web493 web494 web495 web496 web497 web498 web499 web500 web501 web502 web503 web505 web506 web507 web508 web509 web510 web486 扫目录 初始界面尝试文件包含index.php&am…

vue3+vite+js 使用pinia -- vue2 vuex的plus版

先交代下基础版本: “node”:“V16.14.1” “vue”: “^3.4.21” “vite”: “^5.2.0” 接入状态store 即 vuex 呃(⊙﹏⊙)vuex这里可以略过了,我在研究完后,才发现vue3出来个pinia,是vuex的升级,体积更小…

[C#] Visual Studio开发工具编译出错匹配目标平台x86或x64架构问题解决

使用Visual Studio开发工具的NuGet管理包插件时,开发者常常会遇到编译错误。尤其是在切换目标平台架构(如AnyCPU、x86或x64)时,有时会发现切换似乎不起作用,导致编译仍然出错。 文章目录 You need to specify platform…

【项目学习01_2024.04.27_Day01】

学习笔记 项目学习链接第2章 内容管理模块v3.11 模块需求分析1.1 什么是需求分析1.2 模块介绍1.3 业务流程1.4 界面原型 2 创建模块工程2.1 模块工程结构父工程和子工程之间的继承关系以及工程与工程之间的依赖关系,通俗理解:2.2 创建模块工程\pom\含义及…

数据结构 第六章 树与二叉树(五)

🚀 【考纲要求】哈夫曼树和哈夫曼编码、并查集 🚀 第六章第一节内容请查看此链接 树的基本概念 🚀 第六章第二节内容请查看此链接 二叉树的定义、四种特殊的二叉树和二叉树的存储结构 🚀 第六章第三节内容请查看此链接 二叉树的遍…

SpringData JPA - ORM 框架下,打造高效数据访问层

目录 一、SpringData JPA 概述 1.1、什么是 JPA 1.2、什么是 ORM 1.3、什么是 Hibernate 1.4、JPA 和 Hibernate 的关系 1.5、JPA 的优势 二、SpringData JPA 实战开发 2.1、依赖 2.2、配置文件 2.3、启动类 2.4、创建实体 2.5、基于 JpaRepository 的 CRUD 三、…