Java开发中常见的几种替换字典值替换的方法,你会几招?
lipiwang 2024-11-01 14:12 7 浏览 0 评论
前提引入:「开发思路」Java 开发中你是如何处理字典值释义的?
业务场景:在后期的运维维护中,发现创建人在业务表中使用的不是 创建人ID 或 创建人名称,而是使用的是 账号名,而 账号名虽说是唯一的,但全是英文/拼音存储的不满足业务需求,业务需求是需要现在是用户的姓名,你说这……是不是很无语呢?
当然有人会说了,为了查询方便,插入的时候就应该改动过来,然后做一下数据梳理,将数据库的数据找个空闲时间讲创建人ID/创建人账号名处理成存为创建人名称,你说这是不是很好?好好好,当然好,但不是本文的讨论的重点哦
本文讨论重点:基于已运行的系统在查询的时候做一些处理的几种方法。如果有兴趣可以继续了解,欢迎评论探讨!
文章说明:文章只讨论实现思路,不做具体完整的实现案例展示。
零、数据库数据准备
(1)字典表(sys_dict)
CREATE TABLE `sys_dict` (
`id` int(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`type` varchar(100) DEFAULT NULL,
`description` varchar(100) DEFAULT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remarks` varchar(255) DEFAULT NULL,
`system` char(1) DEFAULT '0',
`del_flag` char(1) DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
KEY `sys_dict_del_flag` (`del_flag`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='字典表';
-- 添加测试数据
INSERT INTO pig.sys_dict (`type`,description,create_time,update_time,remarks,`system`,del_flag) VALUES
('dict_type','字典类型','2019-05-16 14:16:20','2019-05-16 14:20:16','系统类不能修改','1','0'),
('log_type','日志类型','2020-03-13 14:21:01','2020-03-13 14:21:01','0-正常 1 异常','1','0');
(2)字典值表(sys_dict_item)
CREATE TABLE `sys_dict_item` (
`id` int(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`dict_id` int(11) NOT NULL,
`value` varchar(100) DEFAULT NULL,
`label` varchar(100) DEFAULT NULL,
`type` varchar(100) DEFAULT NULL,
`description` varchar(100) DEFAULT NULL,
`sort` int(10) NOT NULL DEFAULT '0' COMMENT '排序(升序)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remarks` varchar(255) DEFAULT NULL,
`del_flag` char(1) DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
KEY `sys_dict_value` (`value`) USING BTREE,
KEY `sys_dict_label` (`label`) USING BTREE,
KEY `sys_dict_del_flag` (`del_flag`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='字典项';
-- 添加测试数据字典值项目
INSERT INTO pig.sys_dict_item (dict_id,value,label,`type`,description,sort,create_time,update_time,remarks,del_flag) VALUES
(1,'1','系统类','dict_type','系统类字典',0,'2019-05-16 14:20:40','2019-05-16 14:20:40','不能修改删除','0'),
(1,'0','业务类','dict_type','业务类字典',0,'2019-05-16 14:20:59','2019-05-16 14:20:59','可以修改','0'),
(2,'0','正常','log_type','正常',0,'2020-03-13 14:23:22','2020-03-13 14:23:22','正常','0'),
(2,'9','异常','log_type','异常',1,'2020-03-13 14:23:35','2020-03-13 14:23:35','异常','0');
(3)业务表:系统日志
CREATE TABLE `sys_log` (
`id` bigint(64) NOT NULL AUTO_INCREMENT COMMENT '编号',
`type` char(1) DEFAULT '1' COMMENT '日志类型',
`title` varchar(255) DEFAULT '' COMMENT '日志标题',
`service_id` varchar(32) DEFAULT NULL COMMENT '服务ID',
`create_by` varchar(64) DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remote_addr` varchar(255) DEFAULT NULL COMMENT '操作IP地址',
`user_agent` varchar(1000) DEFAULT NULL COMMENT '用户代理',
`request_uri` varchar(255) DEFAULT NULL COMMENT '请求URI',
`method` varchar(10) DEFAULT NULL COMMENT '操作方式',
`params` text COMMENT '操作提交的数据',
`time` mediumtext COMMENT '执行时间',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标记',
`exception` text COMMENT '异常信息',
PRIMARY KEY (`id`),
KEY `sys_log_create_by` (`create_by`),
KEY `sys_log_request_uri` (`request_uri`),
KEY `sys_log_type` (`type`),
KEY `sys_log_create_date` (`create_time`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='日志表';
-- 测试业务日志表数据插入
INSERT INTO pig.sys_log (`type`,title,service_id,create_by,create_time,update_time,remote_addr,user_agent,request_uri,`method`,params,`time`,del_flag,`exception`) VALUES
('0','添加角色','pig','admin','2021-06-04 10:43:05',NULL,'127.0.0.1','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.37','/role','POST','','6','0',NULL);
一、数据库SQL直接联查替换
-- 方式一,直接查询的时候处理
select
id
, (select label from sys_dict_item sdi where `type` = 'log_type' and sdi.value = sl.`type`) as logLabel
from sys_log sl ;
-- 方式二,关联查询1
select
sl.id
, sdi.label as logLabel
from sys_log sl
left join sys_dict_item sdi on sl.`type` = sdi.value and sdi.`type` = 'log_type' ;
-- 方式三:关联查询2
select id
, sdit.label as logLabel
from sys_log sl
left join (
select value, label from sys_dict_item sdi where sdi.`type` = 'log_type'
) as sdit on sl.`type` = sdit.value
二、mybatis XML 文件 typyHandler 替换处理
自定义一个类型转换器,处理数据替换问题。
(1)创建一个自定义的TypeHandler
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class YesNoTypeHandler extends BaseTypeHandler<Boolean> {
// 从 ResultSet 读取数据并转换为 Java 类型
@Override
public Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException {
String value = rs.getString(columnName);
return "Y".equalsIgnoreCase(value);
}
@Override
public Boolean getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String value = rs.getString(columnIndex);
return "Y".equalsIgnoreCase(value);
}
@Override
public Boolean getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String value = cs.getString(columnIndex);
return "Y".equalsIgnoreCase(value);
}
// 将 Java 类型转换为数据库类型
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter ? "Y" : "N");
}
// 指定该处理器处理的 Java 类型
@Override
public Class<Boolean> getRawType() {
return Boolean.class;
}
// 指定该处理器处理的 JDBC 类型(可选)
@Override
public JdbcType getJdbcType() {
return JdbcType.VARCHAR;
}
}
(2)mybatis-config.xml 中配置 或者 SpringBoot 配置类型转换器存放目录包
<typeHandlers>
<typeHandler handler="com.example.YesNoTypeHandler" javaType="java.lang.Boolean" jdbcType="VARCHAR"/>
</typeHandlers>
@MapperScan(basePackages = "com.example.mapper", typeHandlersPackage = "com.example.typehandler")
@SpringBootApplication
public class YourApplication {
// ...
}
(3)XML 中对应字段配置
<resultMap id="yourResultMap" type="com.example.YourEntity">
<id property="id" column="id" />
<result property="isActive" column="active_flag" typeHandler="com.example.YesNoTypeHandler" />
<!-- 其他字段... -->
</resultMap>
三、Spring Boot 内置 Jackson 序列化处理
(1)准备序列化处理类
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
@Component
@RequiredArgsConstructor // Lombok 的构造器注入
public class UserNameSensitiveDataSerializer extends JsonSerializer<String> {
// 业务处理
private final SysUserPlusService userPlusService;
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
//if (isSensitiveData(value)) { // 假设这是一个检查数据是否敏感的方法
// gen.writeString("***"); // 使用占位符替换敏感数据
//} else {
// gen.writeString(value);
//}
gen.writeString(this.handleUserName(s));// 需要处理替换的业务逻辑
}
//private boolean isSensitiveData(String value) {
// // 实现你的敏感数据检查逻辑
// return false;
//}
private String handleUserName(String userName) {
return Optional.ofNullable(this.userPlusService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userName)))
.orElse(new SysUser()).getName();
}
}
(2)使用此序列化器
public class UserDTO {
// ... 其他字段 ...
@JsonSerialize(using = UserNameSensitiveDataSerializer.class)
private String password;
// ... getter和setter ...
}
四、前端请求自动映射查询
前端读取所有的字典数据缓存于前端,然后需要的业务表格中,从缓存的数据获取匹配即可。(缓存的数据如果调整了,可以通过标记告知前端重新更新缓存数据。)
五、其他方法
- 使用AOP 框架(如 Spring AOP):
- 在数据序列化之前拦截它;
- 然后再 切面中检查数据并处理;
- 使用过滤器或者拦截器:
- 在Web应用程序中,使用过滤器或拦截器在响应发送到客户端之前拦截它。
- 修改响应体中的JSON数据,以替换(或删除敏感)信息。
- 使用 DTO 或者 对应每个接口需要处理的时候通过逻辑替换处理。(比如:先将所有的字典值数据存入缓存(redis/cache/memcache等)中,然后给个公共的查询替换方法,在每个业务接口中替换数据)
相关推荐
- ubuntu单机安装open-falcon极度详细操作
-
备注:以下操作均由本人实际操作并得到验证,喜欢的同学可尝试操作安装。步骤一1.1环境准备(使用系统:ubuntu18.04)1.1.1安装redisubuntu下安装(参考借鉴:https://...
- Linux搭建promtail、loki、grafana轻量日志监控系统
-
一:简介日志监控告警系统,较为主流的是ELK(Elasticsearch、Logstash和Kibana核心套件构成),虽然优点是功能丰富,允许复杂的操作。但是,这些方案往往规模复杂,资源占用高,...
- 一文搞懂,WAF阻止恶意攻击的8种方法
-
WAF(Web应用程序防火墙)是应用程序和互联网流量之间的第一道防线,它监视和过滤Internet流量以阻止不良流量和恶意请求,WAF是确保Web服务的可用性和完整性的重要安全解决方案。它...
- 14配置appvolume(ios14.6配置文件)
-
使用AppVolumes应用程序功能,您可以管理应用程序的整个生命周期,包括打包、更新和停用应用程序。您还可以自定义应用程序分配,以向最终用户提供应用程序的特定版本14.1安装appvolume...
- 目前流行的缺陷管理工具(缺陷管理方式存在的优缺点)
-
摘自:https://blog.csdn.net/jasonteststudy/article/details/7090127?utm_medium=distribute.pc_relevant.no...
- 开源数字货币交易所开发学习笔记(2)——SpringCloud
-
前言码云(Gitee)上开源数字货币交易所源码CoinExchange的整体架构用了SpringCloud,对于经验丰富的Java程序员来说,可能很简单,但是对于我这种入门级程序员,还是有学习的必要的...
- 开发JAX-RPC Web Services for WebSphere(下)
-
在开发JAX-RPCWebServicesforWebSphere(上)一文中,小编为大家介绍了如何创建一个Web服务项目、如何创建一个服务类和Web服务,以及部署项目等内容。接下来小编将为大...
- CXF学习笔记1(cxf client)
-
webservice是发布服务的简单并实用的一种技术了,个人学习了CXF这个框架,也比较简单,发布了一些笔记,希望对笔友收藏并有些作用哦1.什么是webServicewebService让一个程序可...
- 分布式RPC最全详解(图文全面总结)
-
分布式通信RPC是非常重要的分布式系统组件,大厂经常考察的Dubbo等RPC框架,下面我就全面来详解分布式通信RPC@mikechen本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》...
- Oracle WebLogic远程命令执行0day漏洞(CVE-2019-2725补丁绕过)预警
-
概述近日,奇安信天眼与安服团队通过数据监控发现,野外出现OracleWebLogic远程命令执行漏洞最新利用代码,此攻击利用绕过了厂商今年4月底所发布的最新安全补丁(CVE-2019-2725)。由...
- Spring IoC Container 原理解析(spring中ioc三种实现原理)
-
IoC、DI基础概念关于IoC和DI大家都不陌生,我们直接上martinfowler的原文,里面已经有DI的例子和spring的使用示例《InversionofControlContainer...
- Arthas线上服务器问题排查(arthas部署)
-
1Arthas(阿尔萨斯)能为你做什么?这个类从哪个jar包加载的?为什么会报各种类相关的Exception?我改的代码为什么没有执行到?难道是我没commit?分支搞错了?遇到问题无法在...
- 工具篇之IDEA功能插件HTTP_CLENT(idea2021插件)
-
工具描述:Java开发人员通用的开发者工具IDEA集成了HTTPClient功能,之后可以无需单独安装使用PostMan用来模拟http请求。创建方式:1)简易模式Tools->HTTPCl...
- RPC、Web Service等几种远程监控通信方式对比
-
几种远程监控通信方式的介绍一.RPCRPC使用C/S方式,采用http协议,发送请求到服务器,等待服务器返回结果。这个请求包括一个参数集和一个文本集,通常形成“classname.meth...
- 《github精选系列》——SpringBoot 全家桶
-
1简单总结1SpringBoot全家桶简介2项目简介3子项目列表4环境5运行6后续计划7问题反馈gitee地址:https://gitee.com/yidao620/springbo...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- maven镜像 (69)
- undefined reference to (60)
- zip格式 (63)
- oracle over (62)
- date_format函数用法 (67)
- 在线代理服务器 (60)
- shell 字符串比较 (74)
- x509证书 (61)
- localhost (65)
- java.awt.headless (66)
- syn_sent (64)
- settings.xml (59)
- 弹出窗口 (56)
- applicationcontextaware (72)
- my.cnf (73)
- httpsession (62)
- pkcs7 (62)
- session cookie (63)
- java 生成uuid (58)
- could not initialize class (58)
- beanpropertyrowmapper (58)
- word空格下划线不显示 (73)
- jar文件 (60)
- jsp内置对象 (58)
- makefile编写规则 (58)