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

目录

  • 前言
  • 实现思路
    • 技术确定
  • 食用方式
    • 效果
    • 使用样例
    • 项目中使用
      • 第一步 复制包
      • 第二步 实现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.mzph.cn/pingmian/8711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构复习指导之二叉树的概念

文章目录 二叉树 考纲内容 复习提示 1.二叉树的概念 1.1二叉树的定义及其主要特性 1.1.1二叉树的定义 1.1.2几种特殊的二叉树 1.1.3二叉树的性质 1.2二叉树的存储结构 1.2.1顺序存储结构 1.2.2链式存储结构 知识回顾 二叉树 考纲内容 (一)树…

LeetCode 每日一题 2024/4/29-2024/5/5

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步 目录 4/291146. 快照数组4/30 2798. 满足目标工作时长的员工数目5/1 2462. 雇佣 K 位工人的总代价5/2 857. 雇佣 K 名工人的最低成本5/3 1491. 去掉最低工资和最高工资后的工资平…

苹果Mac用户下载VS Code(Universal、Intel Chip、Apple Silicon)哪个版本?

苹果macOS用户既可以下载通用版(Universal),软件将自动检测用户的处理器并进行适配。 也可以根据型号下载对应CPU的版本: 使用Intel CPU的Mac电脑可下载Intel Chip版本; 使用苹果自研M系列CPU的Mac电脑下载Apple Si…

Oracle Patch清理

场景: 在对Oracle安装补丁后,会发现OS上被占用了大量的空间,本文档清理Opatch过程中的一些文件,释放空间 参考文档: Can You Delete $ORACLE_HOME/.patch_storage Directory ? (Doc ID 403218.1) How To Avoid Disk …

【Redis7】10大数据类型之Hash类型

文章目录 1.Hash类型2.常用命令3.示例hset和hgethgetallhlenhkeys和hvalshexistshdelhincrby和hincrbyfloathsetnx 1.Hash类型 Redis中的Hash类型是一种高效的数据结构,用于存储键值对的集合。这种类型特别适用于表示对象,因为它允许你将对象的多个属性…

Context capture/Pix4Dmapper/AutoCAD/CASS/EPS软件的安装流程与使用方法;土方量计算;无人机摄影测量数据处理

目录 专题一 无人机摄影测量技术应用现状及其发展 专题二 基本原理和关键技术讲解 专题三 无人机影像外业数据获取 专题四 数据处理环境建立与软件熟悉 专题五 GNSS数据土方量计算 专题六 基于无人机影像数据的正射影像制作 专题七 基于无人机影像数据的三维模型制作 专…

gocator导出图片

想用3D扫描后的图片,但是系统自带的导出方法很麻烦,所以考虑通过sdk导出 首先需要设置点云亮度 这里是导出图片的关键代码 case GoDataMessageType.SurfaceIntensity: { Debug.WriteLine("SurfaceIntensity "); GoSu…

线段树专题

落谷1607 #include<bits/stdc.h> using namespace std;#define ls u<<1 #define rs u<<1|1const int N 1e5;int n, k, c, ans; struct line {int l, r, m; // m为候车的牛的数量bool operator<(line b) {return r < b.r;} }s[N];struct tree {int l, …

antV X6的简要使用教程

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 在我们的日常开发工作中&#xff0c;我们经常需要构建复杂的交互式图…

【MM32F3270火龙果】点亮led

文章目录 前言GPIO的工作模式一、有哪些工作模式&#xff1f;1.1 GPIO的详细介绍1.2 GPIO的内部框图输入模式输出部分 二、操作GPIO点亮led2.1 初始化gpio2.2 写gpio 三、示例代码总结 前言 本文将介绍如何在MM32F3270火龙果微控制器上使用Keil开发环境点亮LED。MM32F3270火龙…

Java中使用FlatBuffers实现序列化

Java 中的 FlatBuffers有助于高速数据序列化/反序列化&#xff0c;消除解析开销。它由 Google 开发&#xff0c;为跨平台数据交换提供无模式、内存高效的解决方案。 Java 开发人员可以利用其直接内存访问来实现最佳性能和最小内存占用&#xff0c;从而提高应用程序速度、可扩展…

Kamailio openssl 3.0.x 需要注意的事项

我们留意到 Debian Bookworm 安装的 openssl 版本是 3.0.x 这里有几个地方要注意&#xff1a; modparam("tls", "init_mode", 1)核心参数 tls_threads_mode 配置为 1 或者 配置为 2版本建议用 v 5.8.1 参考链接&#xff1a; #3832#3765#3791 目前官方…

北交所佣金费率标准是多少?北交所相关信息科普

北交所的佣金费率并非固定不变&#xff0c;而是可以根据投资者的需求和证券公司的政策进行调整。目前北交所的佣金费率最低是万分之二。 一般来说&#xff0c;北交所的佣金费率默认在万分之三左右&#xff0c;但这不是固定的费率。根据证券公司的不同&#xff0c;佣金费率可以…

绝地求生:PCL第五轮数据出炉,XDD与林树入选最佳阵容,韦神真在做事了

距离PCL季后赛开赛还有两天时间&#xff0c;小梦还沉浸在常规赛最后一场WCG和TSG争名额的关键之战&#xff0c;现在看来WCG硬贴PeRo房区那波真是没道理&#xff0c;只能解释为太想拿分导致上头了&#xff0c;导致决赛圈没有余力限制TSG&#xff0c;但这何尝不是TSG自己的剧本&a…

算法训练Day52 | ● 84.柱状图中最大的矩形

84.柱状图中最大的矩形 class Solution { public:int largestRectangleArea(vector<int>& heights) {stack<int> s;s.push(-1);s.push(0);int space 0;for(int i1; i<heights.size(); i){while(s.top()! -1 && (iheights.size() || heights[i]<…

SAF文件选择与真实路径转换

一、构建选择文件与回调方法 //文件选择回调ActivityResultLauncher<String[]> pickFile registerForActivityResult(new ActivityResultContracts.OpenDocument(), uri->{if (uri ! null) {Log.e("cxy", "返回的uri:" uri);Log.e("cxy&q…

【JavaEE初阶系列】——利用Servlet API实现表白墙网站(1.6w字深刻了解前后端交互逻辑)

目录 &#x1f393;准备工作 &#x1f393;了解前端部分知识(主要JS&#xff09; &#x1f393;前后端交互部分 &#x1f388;主要思路 &#x1f6a9;提交信息 &#x1f36d;让前端发起一个ajax请求 &#x1f36d;服务器读取上述请求&#xff0c;并计算出响应 &#x1…

【Stylus详解与引入】

文章目录 Stylus详解与引入一、Stylus简介二、Stylus的特性1. 变量2. 嵌套规则3. 混合&#xff08;Mixins&#xff09;4. 函数5. 条件语句和循环 三、Stylus的引入与配置1. 安装Stylus和stylus-loader2. 配置Webpack3. 在Vue项目中使用Stylus4. 编译Stylus代码四、Stylus的性能…

Gateway的基本配置

Gateway的基本配置通常涉及网络、路由、安全性以及其他一些关键元素。以下是一个关于Gateway基本配置的详细指南&#xff1a; 网络连接配置&#xff1a; 设备连接&#xff1a;确保网关设备与内部网络的交换机、集线器或服务器/计算机正确连接。网络拓扑结构应支持内外通信。IP地…

2024-05-08 问AI: 在深度学习中,介绍一下RMSProp 优化器

文心一言 在深度学习中&#xff0c;RMSProp&#xff08;Root Mean Square Propagation&#xff09;优化器是一种常用的优化算法&#xff0c;主要用于神经网络训练的梯度下降算法的变体。它是对Adagrad优化器的一种改进&#xff0c;旨在解决Adagrad中学习率过快下降的问题。 R…