91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Mybatis?plus多租戶方案的實戰踩坑分析

發布時間:2021-12-14 14:13:51 來源:億速云 閱讀:474 作者:iii 欄目:開發技術

這篇文章主要介紹“Mybatis plus多租戶方案的實戰踩坑分析”,在日常操作中,相信很多人在Mybatis plus多租戶方案的實戰踩坑分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Mybatis plus多租戶方案的實戰踩坑分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

(一).方案

網上有很多方案,本文只寫最后一種,即:表增加租戶id,實現數據隔離

方案一:增加租戶id,在每一個mapper調用的地方,都手工加上租戶id

例如:

LambdaQueryWrapper<Entity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Entity::getTenantId,"tenantId");
entityMapper.selectList(lambdaQueryWrapper);

這種方式復雜,工作量大,且容易漏。沒有采用

方案二:使用mp官方的多租戶插件,此處代碼省略,自行去官方文檔上查詢

(二).官方多租戶的方案的優化和坑

采用了官方文檔的多租戶插件后,前期調試很順利,crud 都自測過了,以為沒有問題了,于是就發測試環境了,但是隨著測試的深入,發現了好多問題和需要改動的地方,此處列舉:

1.分析哪些需要加多租戶,哪些不需要加

(1)租戶id的重寫

官方的默認重寫方法是:

@Override
public Expression getTenantId() {
    return null;
}

此處需要定義你的租戶id的獲取方法

(2)租戶字段的定義

private static final String TENANT_ID = "tenant_id";

@Override
public String getTenantIdColumn() {
    return TENANT_ID;
}

(3)租戶攔截

@Override
public boolean ignoreTable(String tableName) {
    return TenantLineHandler.super.ignoreTable(tableName);
}

此處我采用的方案是 表名攔截,代碼如下:

@Override
public boolean ignoreTable(String tableName) {

    /**
     * 此處的list,臨時用作攔截
     * 原因是:下面的表解析方法,用的是大駝峰轉下劃線,再跟sql攔截器攔截到的表名對比,如果匹配到了,則認為該表需要多租戶拼接
     * 但是有的表沒有嚴格的按照大駝峰轉下劃線,所以這些表需要額外定義
     * @TableName 這個注解能否完成該職責,目前還未測試,以后再說。
     */
    List<String> list = new ArrayList<>();
    list.add("das_standard_operation");
    list.add("t_expert");
    list.add("t_nominate_dict");
    list.add("t_nominate_dict_history");
    list.add("t_order");
    list.add("t_standard_sort");
    list.add("t_task");
    list.add("t_task_confirm");
    list.add("das_view");
    if (list.contains(tableName)) {
        return false;
    }
    EntityTableCache instance = EntityTableCache.getInstance();
    if (null == instance || null == instance.getCacheData(tableName)) {
        //如果未初始化到,不拼接租戶id
        return true;
    }
    String entityPath = EntityTableCache.getInstance().getCacheData(tableName).toString();
    //該方法會將大駝峰轉為下劃線,并完成初始化
    return !EntityUtils.isHaveAttr(entityPath, COLUMN_TENANTID);
}

EntityUtils 方法代碼如下 (github上的一位小伙子寫的,侵權聯系我刪)

/**
 * 判斷實體是否有某個屬性
 *
 * @param entityPath 實體全路徑
 * @param attrName   屬性名字
 * @return boolean
 */
public static boolean isHaveAttr(String entityPath, String attrName) {
    Optional<String> epOptional = Optional.ofNullable(entityPath);
    if (!epOptional.isPresent()) {
        return false;
    }
    try {
        Class<?> aClass = Thread.currentThread().getContextClassLoader().loadClass(epOptional.get());
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            if (attrName.equals(field.getName())) {
                return true;
            }
        }
        return false;
    } catch (ClassNotFoundException e) {
        // log.error("SystemSqlParser->isHaveAttr類加載異常:" + e.getMessage());
        return false;
    }
}

2.jsqlparser 這個包與pagehelper 版本不對

在自測的時候,發現update語句攔不住,結果發現jsqlparser的版本號是1.2 而1.2與2.0(mp3.4.1 的jspparser版本是2.0),通過debug發現,進到了1.2的update方法

如圖:

Mybatis?plus多租戶方案的實戰踩坑分析

1.2版本是getTables(),而2.0是如圖的getTable()

解決方法:

父pom強制規定版本

</dependencyManagement>
    </dependencies>
        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.10</version>
        </dependency>
    </dependencies>
</dependencyManagement>

3.sql解析失敗

1.regexp

目前發現使用到了regexp > 0 的sql 語句,解析器會報錯

2.replace into 語句

這個語句目前我發現也是不支持的

上述的兩個問題到現在還沒有解決,翻閱了一些資料,問了一些同事,對這塊接觸的都比較少,目前mp最新版本使用的3.4.3.4中使用的com.github.jsqlparser:jsqlparser 是4.2版本,目前對上述的兩條仍然不支持(如果有哪位大神解決了,麻煩評論指導一下!)

解決方法

既然你失敗,那我就不用你好了,手動拼接,見下面忽略方法??

4.忽略多租戶不生效

我們都知道通過注解:@InterceptorIgnore(tenantLine = "on") 可以達到該mapper語句不進行sql解析,和不進行多租戶的改造。但是在實際應用場景中發現有一個特殊的場景該注解不生效。

例如:

Page<Expert> page = PageHelper.startPage(param.getPageNumber(), param.getPageSize());
List<Expert> experts = expertMapper.queryExpertList(page);

這個問題真的是浪費了我好久的時間,后來通過查閱資料,我發現@InterceptorIgnore在有分頁的時候,是會失效的,但是我又想,都是mp的東西,你自己都沖突,那怎么能行。

然后我就發現PageHelper 這個東西,看著很奇怪。然后我就給去掉了,不進行分頁,果然可以了!注解生效了。完美,同時,mp都已經提供了分頁的東西,為什么還要借助com.github的呢。

然后改造如下:

IPage<Expert> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(param.getPageNumber(),param.getPageSize())
List<Expert> experts = expertMapper.queryExpertList(expertMapping.dtoToEntity(param));

到此,關于“Mybatis plus多租戶方案的實戰踩坑分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

伊通| 梁山县| 尚志市| 峡江县| 日照市| 无极县| 宁阳县| 巍山| 红安县| 阳曲县| 江陵县| 壤塘县| 阜宁县| 保康县| 西峡县| 邛崃市| 旬邑县| 军事| 博乐市| 柯坪县| 澳门| 辰溪县| 梅州市| 益阳市| 永康市| 顺义区| 屯门区| 汝城县| 柳林县| 六枝特区| 衢州市| 昌平区| 龙山县| 多伦县| 德格县| 衡水市| 恩平市| 同德县| 安溪县| 遂宁市| 务川|