<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      數(shù)據(jù)分表Mybatis Plus動態(tài)表名最優(yōu)方案的探索

      一、應(yīng)用場景

      大家在使用Mybatis進行開發(fā)的時候,經(jīng)常會遇到一種情況:按照月份month將數(shù)據(jù)放在不同的表里面,查詢數(shù)據(jù)的時候需要跟不同的月份month去查詢不同的表。

      但是我們都知道,Mybatis是ORM持久層框架,即:實體關(guān)系映射,實體Object與數(shù)據(jù)庫表之間是存在一一對應(yīng)的映射關(guān)系。比如:

      @Data
      public class Student {
          private Integer id;
          private String stuName;
          private Integer age;
      }
      

      表結(jié)構(gòu)

      CREATE TABLE `student` (
          `id` INT(11) NOT NULL AUTO_INCREMENT,
          `stu_name` VARCHAR(64) NOT NULL DEFAULT '0' COMMENT '姓名',
          `age` INT(11) NOT NULL COMMENT '年齡',
          PRIMARY KEY (`id`)
      )
      COMMENT='學(xué)生表'
      COLLATE='utf8_general_ci'
      ENGINE=InnoDB
      ;
      

      Student 實體類與student表是一一對應(yīng)的關(guān)系,如果我們希望將學(xué)員表按照月份進行分表,比如:student_202206、student_202207、student_202208,即產(chǎn)生了一個實體類及其Mapper需要操作多個數(shù)據(jù)庫分月表,這種情況在Mybatis plus下我們該如何操作數(shù)據(jù)呢? 其實方法有很多,我將我實踐中總結(jié)出的最優(yōu)方案給大家進行說明。

      二、動態(tài)表名處理器接口實現(xiàn)

      為了處理上述類似的問題,mybatis plus提供了動態(tài)表名處理器接口TableNameHandler,我們只需要實現(xiàn)這個接口,并將這個接口應(yīng)用配置生效,即可實現(xiàn)動態(tài)表名。

      需要注意的是:

      • 在mybatis plus 3.4版本之前,動態(tài)表名處理器接口是ITableNameHandler, 需要配合mybatis plus分頁插件一起使用才能生效。我們這里只介紹3.4版本之后的實現(xiàn)方式。
      • 在mybatis plus 3.4.3.2 作廢該的方式:dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map); 大家如果見到這種方式實現(xiàn)的動態(tài)表名,也是過時的實現(xiàn)方法,新版本中該方法已經(jīng)刪除。

      經(jīng)過我一段時間的實踐總結(jié),我的實現(xiàn)類如下(基于mybatis plus 3.4.3.2之后的版本):

      import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
      
      import java.util.Arrays;
      import java.util.List;
      
      /**
       * 按月份參數(shù),組成動態(tài)表名
       */
      public class MonthTableNameHandler implements TableNameHandler {
      
          //用于記錄哪些表可以使用該月份動態(tài)表名處理器(即哪些表按月分表)
          private List<String> tableNames;
          //構(gòu)造函數(shù),構(gòu)造動態(tài)表名處理器的時候,傳遞tableNames參數(shù)
          public MonthTableNameHandler(String ...tableNames) {
              this.tableNames = Arrays.asList(tableNames);
          }
      
          //每個請求線程維護一個month數(shù)據(jù),避免多線程數(shù)據(jù)沖突。所以使用ThreadLocal
          private static final ThreadLocal<String> MONTH_DATA = new ThreadLocal<>();
          //設(shè)置請求線程的month數(shù)據(jù)
          public static void setData(String month) {
              MONTH_DATA.set(month);
          }
          //刪除當(dāng)前請求線程的month數(shù)據(jù)
          public static void removeData() {
              MONTH_DATA.remove();
          }
      
          //動態(tài)表名接口實現(xiàn)方法
          @Override
          public String dynamicTableName(String sql, String tableName) {
              if (this.tableNames.contains(tableName)){
                  return tableName + "_" + MONTH_DATA.get();  //表名增加月份后綴
              }else{
                  return tableName;   //表名原樣返回
              }
          }
      }
      

      大家先對上面的代碼有一個基礎(chǔ)了解,看了下面的測試過程,再回頭看上面的代碼中的注釋,就比較好理解了。表名處理器寫好了之后,我們要讓它生效,還需要做如下的配置。配置內(nèi)容照葫蘆畫瓢就可以了。需要關(guān)注的部分,我都已經(jīng)給大家添加了注釋。

      @Configuration
      @MapperScan("com.zimug")
      public class MybatisPlusConfig {
      
          @Bean
          public MybatisPlusInterceptor mybatisPlusInterceptor() {
              MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
              DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
              dynamicTableNameInnerInterceptor.setTableNameHandler(
                      //可以傳多個表名參數(shù),指定哪些表使用MonthTableNameHandler處理表名稱
                      new MonthTableNameHandler("student","teacher") 
              );
              //以攔截器的方式處理表名稱
              interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
              //可以傳遞多個攔截器,即:可以傳遞多個表名處理器TableNameHandler
              //interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
              return interceptor;
          }
      }
      

      三、測試實現(xiàn)效果

      首先創(chuàng)建一個StudentMapper ,默認(rèn)情況下StudentMapper 只能操作student表,不能操作student_YYYYMM表。

      @Mapper
      public interface StudentMapper extends BaseMapper<Student> {}
      

      下面我們來寫一個單元測試用例,該測試用例test函數(shù)模擬一次請求訪問的Controller或者service函數(shù)。

      @SpringBootTest
      class DynamicTableNameTest {
          @Resource
          private StudentMapper studentMapper;
      
          @Test
          void test() {
              //執(zhí)行數(shù)據(jù)操作之前設(shè)置月份(實際場景下該參數(shù)從請求參數(shù)中解析)
              MonthTableNameHandler.setData("202208");
              studentMapper.selectById(1); //以id=2查詢student_202208這張表
              //閱后即焚,將ThreadLocal當(dāng)前請求線程的數(shù)據(jù)移除
              MonthTableNameHandler.removeData();
          }
      }
      

      當(dāng)我們執(zhí)行這個單元測試用例的時候,我們發(fā)現(xiàn)控制臺打印出如下信息,注意看SQL的部分,真的是去查詢student_202208這張表了,而不是student表。這說明我們的動態(tài)表名實現(xiàn)是成功的。

      歡迎關(guān)注我的公告號:字母哥雜談,回復(fù)003贈送作者專欄《docker修煉之道》的PDF版本,30余篇精品docker文章。字母哥博客:zimug.com

      posted @ 2022-08-12 15:12  字母哥博客  閱讀(7066)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久草热8精品视频在线观看| 精品无码国产一区二区三区AV| 久久天天躁狠狠躁夜夜躁2o2o | 国产婷婷精品av在线| 国产亚洲av手机在线观看| 制服丝袜中文字幕在线| 亚洲天堂亚洲天堂亚洲色图| 精品国产大片中文字幕| 华人在线亚洲欧美精品| 国产一级小视频| 国产偷国产偷亚洲清高| 日韩成人高精品一区二区| 欧美一区二区| 综合区一区二区三区狠狠| 久久99精品久久久久久9| 国产一区二区日韩经典| 久久欧洲精品成av人片| 久久99精品久久久久麻豆 | 久久人人爽人人人人爽av| 亚洲人午夜精品射精日韩| 国产精品日日摸夜夜添夜夜添无码| 免费无码无遮挡裸体视频在线观看| 亚洲男人的天堂一区二区| 亚洲欧美在线一区中文字幕| 婷婷综合亚洲| 南郑县| 一区二区三区国产不卡| 国产女人在线视频| 67194亚洲无码| 西西444www高清大胆| 亚洲国产精品ⅴa在线观看| 亚洲黄色成人网在线观看| 午夜福利片1000无码免费| 国产午夜无码视频在线观看| 一区二区三区四区高清自拍| 亚洲欧洲色图片网站| 久久亚洲精品人成综合网| 亚洲中文字幕日产无码成人片 | 四虎成人高清永久免费看| 国产对白老熟女正在播放| 国产久免费热视频在线观看|