根據(jù)環(huán)境不同蹋盆,修改表名添加數(shù)據(jù)庫(kù)名

一费薄、前戲

故事背景

公司引入一套阿里云的大數(shù)據(jù)系統(tǒng),匯集公司的多張表栖雾。
正式環(huán)境使用的是大數(shù)據(jù)中間件2.0楞抡,正式環(huán)境是3.0,3.0環(huán)境查詢(xún)需要 “數(shù)據(jù)庫(kù)名.表名”岩灭,2.0環(huán)境查詢(xún)需要“表名”拌倍。
需要實(shí)現(xiàn)一個(gè)根據(jù)環(huán)境不同,修改表名的功能噪径。

常見(jiàn)的技術(shù)方案選型

二、正文

配置文件bootstrap.yml

 # 正式站與測(cè)試站表明對(duì)應(yīng)配置文件
# 正式站表名: 測(cè)試站表名
dataworks:
  tableName:
    prodTableName: testDataBaseName.testTableName

解析配置信息

/**
 * @Auther: fatsnake
 * @Description":
 * @Date:2022/9/14 13:18
 * Copyright (c) 2022, zaodao All Rights Reserved.
 */
@Configuration
@ConfigurationProperties(prefix = "dataworks")
public class DataBaseTableNameConfig {

    /**
     * 表名集合
     */
    private Map<String, String> tableName;

    /**
     * 構(gòu)造函數(shù)
     */
    DataBaseTableNameConfig() {
    }

    public Map<String, String> getTableName() {
        return tableName;
    }

    public void setTableName(Map<String, String> tableName) {
        this.tableName = tableName;
    }

    @Override
    public String toString() {
        return "DataBaseTableNameConfig{"
                + "tableName=" + tableName
                + '}';
    }
}

mybatis插件按環(huán)境條件生效

@Profile({"dev", "test"})
public class FrameMyBatisPluginConfig {

    /**
     *
     * @param sqlSessionFactory sqlSessionFactory
     * @return String
     */
    @Bean
    public String sqlTableNameHandleInterceptor(SqlSessionFactory sqlSessionFactory) {
        //實(shí)例化插件
        SQLTableNameHandleInterceptor sqlTableNameHandleInterceptor = new SQLTableNameHandleInterceptor();
        // 為后續(xù)留好擴(kuò)展
//        //創(chuàng)建屬性值
//        Properties properties = new Properties();
//        properties.setProperty("prop1","value1");
//        //將屬性值設(shè)置到插件中
//        sqlTableNameHandleInterceptor.setProperties(properties);
        //將插件添加到SqlSessionFactory工廠(chǎng)
        sqlSessionFactory.getConfiguration().addInterceptor(sqlTableNameHandleInterceptor);
        return "interceptor";
    }
}

使用mybatis的StatementHandler插件意狠,在sql執(zhí)行前進(jìn)行攔截

此處使用了druid的工具類(lèi)粟关,解析表名,替換表名后重寫(xiě)表名

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.util.JdbcConstants;

/**
 * @Auther: fatsnake
 * @Description":
 * @Date:2022/9/14 12:47
 * Copyright (c) 2022, zaodao All Rights Reserved.
 */
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class SQLTableNameHandleInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        DataBaseTableNameConfig dataBaseTableNameConfig
                = (DataBaseTableNameConfig)SpringContextUtils.getBean("dataBaseTableNameConfig");
        Map<String, String> tableNameMap = dataBaseTableNameConfig.getTableName();
        if (!CollectionUtils.isEmpty(tableNameMap)) {
            StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
            MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, new DefaultObjectFactory(),
                    new DefaultObjectWrapperFactory(), new DefaultReflectorFactory());
            BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");

            String sql = boundSql.getSql();
            List<SQLStatement> stmtList  = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
            MySqlExportTableAliasVisitor visitor = new MySqlExportTableAliasVisitor();
            for (SQLStatement stmt : stmtList) {
                stmt.accept(visitor);
            }
            String handleSQL = SQLUtils.toSQLString(stmtList, JdbcConstants.MYSQL);

            metaStatementHandler.setValue("delegate.boundSql.sql", handleSQL);
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }

實(shí)際替換操作

/**
 * @Auther: fatsnake
 * @Description":
 * @Date:2022/9/14 12:46
 * Copyright (c) 2022, zaodao All Rights Reserved.
 */
public class MySqlExportTableAliasVisitor extends MySqlASTVisitorAdapter {
    @Override
    public boolean visit(SQLExprTableSource x) {
        DataBaseTableNameConfig dataBaseTableNameConfig
                = (DataBaseTableNameConfig) SpringContextUtils.getBean("dataBaseTableNameConfig");
        Map<String, String> tableNameMap = dataBaseTableNameConfig.getTableName();
        if (tableNameMap.containsKey(x.getExpr().toString())) {
            x.setExpr(tableNameMap.get(x.getExpr().toString()));
        }
        return true;
    }
} 

三环戈、尾聲

本來(lái)不了解這個(gè)mybatis的插件機(jī)制的闷板,當(dāng)時(shí)接到這個(gè)需求時(shí),只是想著如何無(wú)感知的讓業(yè)務(wù)開(kāi)發(fā)人員使用院塞,并且項(xiàng)目便于維護(hù)sql遮晚,最好不要維護(hù)兩套sql,經(jīng)過(guò)百度老師的指導(dǎo)拦止,整合形成了這個(gè)結(jié)束解決方案县遣。
暴露出,對(duì)常用的中間件 還是不熟悉啊创泄,源代碼讀的還是少……

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末艺玲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鞠抑,更是在濱河造成了極大的恐慌饭聚,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搁拙,死亡現(xiàn)場(chǎng)離奇詭異秒梳,居然都是意外死亡法绵,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)酪碘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)朋譬,“玉大人,你說(shuō)我怎么就攤上這事兴垦♂阌” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵探越,是天一觀的道長(zhǎng)狡赐。 經(jīng)常有香客問(wèn)我,道長(zhǎng)钦幔,這世上最難降的妖魔是什么枕屉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮鲤氢,結(jié)果婚禮上搀擂,老公的妹妹穿的比我還像新娘。我一直安慰自己卷玉,他們只是感情好哨颂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著相种,像睡著了一般咆蒿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蚂子,一...
    開(kāi)封第一講書(shū)人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音缭黔,去河邊找鬼食茎。 笑死,一個(gè)胖子當(dāng)著我的面吹牛馏谨,可吹牛的內(nèi)容都是我干的别渔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼惧互,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼哎媚!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起喊儡,我...
    開(kāi)封第一講書(shū)人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拨与,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后艾猜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體买喧,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捻悯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了淤毛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片今缚。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖低淡,靈堂內(nèi)的尸體忽然破棺而出姓言,到底是詐尸還是另有隱情,我是刑警寧澤蔗蹋,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布何荚,位于F島的核電站,受9級(jí)特大地震影響纸颜,放射性物質(zhì)發(fā)生泄漏兽泣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一胁孙、第九天 我趴在偏房一處隱蔽的房頂上張望唠倦。 院中可真熱鬧,春花似錦涮较、人聲如沸稠鼻。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)候齿。三九已至,卻和暖如春闺属,著一層夾襖步出監(jiān)牢的瞬間慌盯,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工掂器, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亚皂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓国瓮,卻偏偏與公主長(zhǎng)得像灭必,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乃摹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • SpringData簡(jiǎn)介 對(duì)于數(shù)據(jù)訪(fǎng)問(wèn)層禁漓,無(wú)論是SQL還是NoSQL,在SpringBoot 底層都是采用Spri...
    勿念及時(shí)雨閱讀 564評(píng)論 0 1
  • 一孵睬、重點(diǎn)知識(shí) git 監(jiān)視的是文件內(nèi)容的修改 $ git checkout -- abc.txt : 其實(shí)是用版本...
    一花一世界yu閱讀 893評(píng)論 0 2
  • 本文簡(jiǎn)介 為什么使用SpringBoot 搭建怎樣一個(gè)環(huán)境 開(kāi)發(fā)環(huán)境 導(dǎo)入快速啟動(dòng)項(xiàng)目 集成前準(zhǔn)備 集成Mybat...
    云朵朵朵朵朵閱讀 347評(píng)論 0 0
  • 一播歼、Spring Data 簡(jiǎn)介 Sping Data 官網(wǎng)[https://spring.io/projects...
    yjtuuige閱讀 2,152評(píng)論 0 1
  • 概述 數(shù)據(jù)庫(kù)是一堆數(shù)據(jù)的集合 數(shù)據(jù)庫(kù)有若干張數(shù)據(jù)表,每個(gè)表中有一些數(shù)據(jù) 數(shù)據(jù)庫(kù)是一個(gè)存放所有數(shù)據(jù)的最大單位 一個(gè)數(shù)...
    bowen_wu閱讀 430評(píng)論 0 0