<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用MyBatisPlus實(shí)現(xiàn)多租戶功能

          共 6998字,需瀏覽 14分鐘

           ·

          2022-08-03 13:29


          來源:blog.csdn.net/weixin_38111957/

          article/details/101161660

          • 一、引言
          • 二、具體實(shí)現(xiàn)
          • 三、特定SQL過濾

          一、引言

          我先解釋一下什么叫多租戶,什么場(chǎng)景下使用多租戶。

          多租戶是一種軟件架構(gòu)技術(shù),在多用戶的環(huán)境下,共有同一套系統(tǒng),并且要注意數(shù)據(jù)之間的隔離性。

          舉個(gè)實(shí)際例子:小編曾經(jīng)開發(fā)過一套H5程序,這套程序應(yīng)用在不同醫(yī)院的APP上,當(dāng)醫(yī)院患者下載醫(yī)院APP,并且進(jìn)入相對(duì)應(yīng)的H5頁面,APP則會(huì)把用戶相關(guān)數(shù)據(jù)傳輸?shù)叫【庍@里。在傳輸?shù)臅r(shí)候需要帶上醫(yī)院標(biāo)識(shí)(租戶ID),以便小編將數(shù)據(jù)進(jìn)行隔離。

          當(dāng)不同的租戶使用同一套程序,這里就需要考慮一個(gè)數(shù)據(jù)隔離的情況。

          數(shù)據(jù)隔離有三種方案:

          1. 獨(dú)立數(shù)據(jù)庫(kù):簡(jiǎn)單來說就是一個(gè)租戶使用一個(gè)數(shù)據(jù)庫(kù),這種數(shù)據(jù)隔離級(jí)別最高,安全性最好,但是提高成本。
          2. 共享數(shù)據(jù)庫(kù)、隔離數(shù)據(jù)架構(gòu):多租戶使用同一個(gè)數(shù)據(jù)褲,但是每個(gè)租戶對(duì)應(yīng)一個(gè)Schema(數(shù)據(jù)庫(kù)user)。
          3. 共享數(shù)據(jù)庫(kù)、共享數(shù)據(jù)架構(gòu):使用同一個(gè)數(shù)據(jù)庫(kù),同一個(gè)Schema,但是在表中增加了租戶ID的字段,這種共享數(shù)據(jù)程度最高,隔離級(jí)別最低。

          二、具體實(shí)現(xiàn)

          這里采用方案三,即共享數(shù)據(jù)庫(kù),共享數(shù)據(jù)架構(gòu),因?yàn)檫@種方案服務(wù)器成本最低,但是提高了開發(fā)成本。

          所以MP就提供了一種多租戶的解決方案,實(shí)現(xiàn)方式是基于分頁插件進(jìn)行實(shí)現(xiàn)的,具體實(shí)現(xiàn)代碼如下:

          @Configuration
          public class MyBatisPlusConfig {
              /**
               * 分頁插件
               *
               * @return
               */

              @Bean
              public PaginationInterceptor paginationInterceptor() {
                  PaginationInterceptor paginationInterceptor = new PaginationInterceptor();

                  // 創(chuàng)建SQL解析器集合
                  List<ISqlParser> sqlParserList = new ArrayList<>();

                  // 創(chuàng)建租戶SQL解析器
                  TenantSqlParser tenantSqlParser = new TenantSqlParser();

                  // 設(shè)置租戶處理器
                  tenantSqlParser.setTenantHandler(new TenantHandler() {
                      @Override
                      public Expression getTenantId() {
                          // 設(shè)置當(dāng)前租戶ID,實(shí)際情況你可以從cookie、或者緩存中拿都行
                          return new StringValue("jiannan");
                      }

                      @Override
                      public String getTenantIdColumn() {
                          // 對(duì)應(yīng)數(shù)據(jù)庫(kù)租戶ID的列名
                          return "tenant_id";
                      }

                      @Override
                      public boolean doTableFilter(String tableName) {
                          // 是否需要需要過濾某一張表
                        /*  List<String> tableNameList = Arrays.asList("sys_user");
                          if (tableNameList.contains(tableName)){
                              return true;
                          }*/

                          return false;
                      }
                  });

                  sqlParserList.add(tenantSqlParser);
                  paginationInterceptor.setSqlParserList(sqlParserList);

                  return paginationInterceptor;
              }
          }

          配置好之后,不管是查詢、新增、修改刪除方法,MP都會(huì)自動(dòng)加上租戶ID的標(biāo)識(shí),測(cè)試如下:

          @Test
          public void select(){
              List<User> users = userMapper.selectList(Wrappers.<User>lambdaQuery().eq(User::getAge, 18));
              users.forEach(System.out::println);
          }
          DEBUG==>  Preparing: SELECT id, login_name, name, password, email, salt, sex, age, phone, user_type, status, organization_id, create_time, update_time, version, tenant_id FROM sys_user WHERE sys_user.tenant_id = 'jiannan' AND is_delete = '0' AND age = ? 
          DEBUG==> Parameters: 18(Integer)
          DEBUG<==      Total: 0

          三、特定SQL過濾

          如果在程序中,有部分SQL不需要加上租戶ID的表示,需要過濾特定的sql,可以通過如下兩種方式:

          方式一:在配置分頁插件中加上配置ISqlParserFilter解析器,如果配置SQL很多,比較麻煩,不建議。

          paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
              @Override
              public boolean doFilter(MetaObject metaObject) {
                  MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
                  // 對(duì)應(yīng)Mapper、dao中的方法
                  if("com.example.demo.mapper.UserMapper.selectList".equals(ms.getId())){
                      return true;
                  }
                  return false;
              }
          });

          方式二:通過租戶注解的形式,目前只能作用于Mapper的方法上。

          /**
           * 用戶 Mapper 接口
           */

          public interface UserMapper extends BaseMapper<User{

              /**
               * 自定Wrapper修改
               *
               * @param userWrapper 條件構(gòu)造器
               * @param user        修改的對(duì)象參數(shù)
               * @return
               */

              @SqlParser(filter = true)
              int updateByMyWrapper(@Param(Constants.WRAPPER) Wrapper<User> userWrapper, @Param("user") User user);

          }
          # 開啟 SQL 解析緩存注解生效,如果你的MP版本在3.1.1及以上則不需要配置
          mybatis-plus:
            global-config:
              sql-parser-cache: true

          現(xiàn)在各大廠內(nèi)卷的非常厲害,基于 2b 的 saas 系統(tǒng)正在蓬勃發(fā)展,多學(xué)一些這方面的經(jīng)驗(yàn),對(duì)職業(yè)發(fā)展多少有些幫助!本文就講到這里,感謝大家閱讀!

          程序汪資料鏈接

          程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理

          Java項(xiàng)目分享  最新整理全集,找項(xiàng)目不累啦 07版

          堪稱神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門到實(shí)戰(zhàn)進(jìn)階

          臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開放下載!

          臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開放下載!

          字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開放下載!


          歡迎添加程序汪個(gè)人微信 itwang009  進(jìn)粉絲群或圍觀朋友圈

          瀏覽 67
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕久久人妻被中出一区精品 | 国产骚逼精品视频 | 40岁无码视频看看 | 免费观看日韩a | 无码野外|