首页 > 其他分享 >工作六年,再看到这样的代码,内心五味杂陈......

工作六年,再看到这样的代码,内心五味杂陈......

时间:2024-12-06 20:01:44浏览次数:6  
标签:五味杂陈 ...... 环境 #### env 注解 代码

那天下午,看到了令我终生难忘的代码,那一刻破防了…

Java学习包传送门

故事还得从半年前数据隔离的那个事情说起…

1历史背景

1.1 数据隔离

预发,灰度,线上环境共用一个数据库。每一张表有一个 env 字段,环境不同值不同。特别说明:env 字段即环境字段。如下图所示:

1.2 隔离之前

插曲:一开始只有 1 个核心表有 env 字段,其他表均无该字段;有一天预发环境的操作影响到客户线上的数据。为了彻底隔离,剩余的二十几个表均要添加上环境隔离字段。

当时二十几张表已经大量生产数据,隔离需要做好兼容过渡,保障数据安全。

1.3 隔离改造

其他表历史数据很难做区分,于是新增加的字段 env 初始化 all ,表示预发线上都能访问。以此达到历史数据的兼容。

每一个环境都有一个自己独立标志;从 application.properties 中读该字段;最终到数据库执行的语句如下:

SELECT XXX FROM tableName WHERE env = ${环境字段值} and ${condition}

1.4 隔离方案

最拉胯的做法:每一张表涉及到的 DO、Mapper、XML等挨个添加 env 字段。但我指定不能这么干!!!

具体方案:自定义 mybatis 拦截器进行统一处理。通过这个方案可以解决以下几个问题:

  • 业务代码不用修改,包括 DO、Mapper、XML等。只修改 mybatis 拦截的逻辑。
  • 挨个添加补充字段,工程量很多,出错概率极高
  • 后续扩展容易

1.5 最终落地

在 mybatis 拦截器中, 通过改写 SQL。新增时填充环境字段值,查询时添加环境字段条件。真正实现改一处即可。考虑历史数据过渡,将 env = 当前环境修改成 e n v i n ( {当前环境} 修改成 env in ( 当前环境修改成envin({当前环境},‘all’)

SELECT xxx FROM ${tableName} WHERE env in (${当前环境},'all') AND ${其他条件}

具体实现逻辑如下图所示:

  1. 其中 env 字段是从 application.properties 配置获取,全局唯一,只要环境不同,env 值不同
  2. 借助 JSqlParser 开源工具,改写 sql 语句,修改重新填充、查询拼接条件即可。

思路:自定义拦截器,填充环境参数,修改 sql 语句,下面是部分代码示例:

@Intercepts(
        {@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})}
)
@Component
public class EnvIsolationInterceptor implements Interceptor {
    ......
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        ......
        if (SqlCommandType.INSERT == sqlCommandType) {
            try {
                // 重写 sql 执行语句,填充环境参数等
                insertMethodProcess(invocation, boundSql);
            } catch (Exception exception) {
                log.error("parser insert sql exception, boundSql is:" + JSON.toJSONString(boundSql), exception);
                throw exception;
            }
        }

        return invocation.proceed();
    }
}

一气呵成,完美上线。

2发展演变

2.1 业务需求

随着业务发展,出现了以下需求:

  • 上下游合作,我们的 PRC 接口在匹配环境上与他们有差异,需要改造

    SELECT * FROM ${tableName} WHERE bizId = ${bizId} and env in (?,‘all’)

  • 有一些环境的数据相互相共享,比如预发和灰度等

  • 开发人员的部分后面,希望在预发能纠正线上数据等

2.2 初步沟通

这个需求的落地交给了来了快两年的小鲜肉。在开始做之前,他也问我该怎么做;我简单说了一些想法,比如可以跳过环境字段检查,不拼接条件;或者拼接所有条件,这样都能查询;亦或者看一下能不能注解来标志特定方法,你想一想如何实现…

(●ˇ∀ˇ●)年纪大了需要给年轻人机会。

2.3 勤劳能干

小鲜肉,没多久就实现了。不过有一天下午他遇到了麻烦。他填充的环境字段取出来为 null,看来很久没找到原因,让我帮他看看。(不久前也还教过他 Arthas 如何使用呢,这种问题应该不在话下吧

标签:五味杂陈,......,环境,####,env,注解,代码
From: https://blog.csdn.net/Q2024107/article/details/144274973

相关文章

  • 牛顿法 - Python代码
    牛顿法(Newton'sMethod)是一种用于求解非线性方程的数值方法。其核心思想是通过迭代的方式,在每次迭代中利用当前点的梯度和二阶导数来更新解的估计值。往期梯度下降法:梯度下降法-Python代码-CSDN博客一维问题:        泰勒展开是数学中的一种方法,通过对函数在某一......
  • 常规加载器技术(Conventional Loader Techniques)主要用于操作系统中,负责将程序加载到内
    在Web开发中,常规加载器和高阶技巧加载器(或优化器)是实现更高效资源加载和提升性能的关键技术。常规加载器通常是一些基础的加载机制,而高阶技巧加载器则是更高级的优化方法,能够精细化地控制资源的加载时机和顺序,提升页面的加载性能和用户体验。常规加载器(基础加载器)懒加载(Lazy......
  • (王道练习代码仓库)408考研真题2022 年42题————C语言
    题目:代码实现:#include<stdio.h>#include<stdlib.h>#include<time.h>#include<string.h>typedefintElemType;typedefstruct{ ElemType*elem; intTableLen;}SSTable;voidST_Init(SSTable&ST,intlen)//申请空间,并进行随机数生成{ ST.Ta......
  • 使用lumerical脚本语言创建绘制波导并进行数据分析(纯代码实现)(1)
            使用lumerical脚本语言创建绘制波导、配置二维模式求解器、计算模式轮廓、计算有效折射率(neff)和群折射率(ng)随波长的变化关系、计算有效折射率(neff)随波导宽度的变化关系及针对有效折射率法进行相关数据处理(代码均有注释详解)。一、绘制波导结构1.1代码实现......
  • 低代码技术普及,中国企业数字化门槛持续降低
    随着信息技术的飞速发展,数字化转型已成为企业提升竞争力的关键手段。然而,传统软件开发的高成本、长周期和专业技能要求,往往成为中小企业数字化转型的障碍。近年来,低代码技术的兴起和普及,正在为中国企业数字化转型打开新的大门,显著降低企业进入数字化领域的门槛。低代码技术概......
  • vue3开发中常见的代码错误或者其他相关问题小文章2.0
    11. 条件渲染和列表渲染中的性能问题错误示例:使用v-if和v-for在同一元素上可能导致性能问题。<!--不推荐--><divv-for="iteminitems"v-if="item.isVisible">{{item.name}}</div>解决方案:尽量避免在同一元素上同时使用v-if和v-for。如果需要过滤数据,......
  • 二分查找及java代码实现
    二分查找(BinarySearch)是一种在有序数组中查找特定元素的搜索算法。它通过比较数组中间元素与目标值来确定目标值所在的范围,然后在这个范围内继续进行二分查找,直到找到目标值或确定目标值不存在。二分查找的基本步骤:1. 初始化:设置两个指针,一个指向数组的开始(low),另一个指向......
  • SAP Fiori界面上输入事务代码的设置
    SAPFiori界面上输入事务代码的设置   登录Fiori主页后,随便点击一个子菜单,比如CreateBatch,    进入如下界面,点击Menu,   然后点击Settings...,进入如下界面,   将’ShowOKCode’field栏位右边的按钮点一下,   然后保存。  后续就可以输......
  • AE安装失败说msvcp110.dll 运行错误代码怎么解决?总结五种有效方法
    msvcp110.dll是MicrosoftVisualC++2012运行时库的关键组件,它为基于C++开发的应用程序提供必要的支持。这个动态链接库(DLL)文件包含了实现C++标准库功能的代码,允许开发者在Windows操作系统上构建和运行C++程序。功能和重要性msvcp110.dll文件的重要性体现在以下几个方面:C++......
  • PCA(主成分分析法)原理以及应用+代码实现
    前言 PCA多用于对数据特征集进行降维,也方便对数据集进行可视化操作,说白了最后进行结果展示那么多特征向量要一起表示的话肯定很难展示,超过三维的数据就很难展示了。而PCA可对特征集进行简化,通俗的来讲也就是合并好理解。PCA应用的范围很广因此很有必要要学习,原理肯定还是数学证......