<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
大家在使用Mybatis進行開發的時候,經常會遇到一種情況:按照月份month將資料放在不同的表裡面,查詢資料的時候需要跟不同的月份month去查詢不同的表。
但是我們都知道,Mybatis是ORM持久層框架,即:實體關係對映,實體Object與資料庫表之間是存在一一對應的對映關係。
比如:
@Data public class Student { private Integer id; private String stuName; private Integer age; }
表結構:
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='學生表' COLLATE='utf8_general_ci' ENGINE=InnoDB ;
Student 實體類與student表是一一對應的關係,如果我們希望將學員表按照月份進行分表,比如:student_202206、student_202207、student_202208,即產生了**「一個實體類及其Mapper需要操作多個資料庫分月表,這種情況在Mybatis plus下我們該如何運算元據呢?」** 其實方法有很多,我將我實踐中總結出的最優方案給大家進行說明。
為了處理上述類似的問題,mybatis plus提供了動態表名處理器介面TableNameHandler
,我們只需要實現這個介面,並將這個介面應用設定生效,即可實現動態表名。
需要注意的是:
- 在mybatis plus 3.4版本之前,動態表名處理器介面是
ITableNameHandler
, 需要配合mybatis plus分頁外掛一起使用才能生效。我們這裡只介紹3.4版本之後的實現方式。- 在mybatis plus 3.4.3.2 作廢該的方式:dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map); 大家如果見到這種方式實現的動態表名,也是過時的實現方法,新版本中該方法已經刪除。
經過我一段時間的實踐總結,我的實現類如下(基於mybatis plus 3.4.3.2之後的版本):
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler; import java.util.Arrays; import java.util.List; /** * 按月份引數,組成動態表名 */ public class MonthTableNameHandler implements TableNameHandler { //用於記錄哪些表可以使用該月份動態表名處理器(即哪些表按月分表) private List<String> tableNames; //建構函式,構造動態表名處理器的時候,傳遞tableNames引數 public MonthTableNameHandler(String ...tableNames) { this.tableNames = Arrays.asList(tableNames); } //每個請求執行緒維護一個month資料,避免多執行緒資料衝突。所以使用ThreadLocal private static final ThreadLocal<String> MONTH_DATA = new ThreadLocal<>(); //設定請求執行緒的month資料 public static void setData(String month) { MONTH_DATA.set(month); } //刪除當前請求執行緒的month資料 public static void removeData() { MONTH_DATA.remove(); } //動態表名介面實現方法 @Override public String dynamicTableName(String sql, String tableName) { if (this.tableNames.contains(tableName)){ return tableName + "_" + MONTH_DATA.get(); //表名增加月份字尾 }else{ return tableName; //表名原樣返回 } } }
大家先對上面的程式碼有一個基礎瞭解,看了下面的測試過程,再回頭看上面的程式碼中的註釋,就比較好理解了。表名處理器寫好了之後,我們要讓它生效,還需要做如下的設定。設定內容照葫蘆畫瓢就可以了。需要關注的部分,我都已經給大家新增了註釋。
@Configuration @MapperScan("com.zimug") public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor(); dynamicTableNameInnerInterceptor.setTableNameHandler( //可以傳多個表名引數,指定哪些表使用MonthTableNameHandler處理表名稱 new MonthTableNameHandler("student","teacher") ); //以攔截器的方式處理表名稱 interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor); //可以傳遞多個攔截器,即:可以傳遞多個表名處理器TableNameHandler //interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor); return interceptor; } }
首先建立一個StudentMapper ,預設情況下StudentMapper 只能操作student表,不能操作student_YYYYMM表。
@Mapper public interface StudentMapper extends BaseMapper<Student> {}
下面我們來寫一個單元測試用例,該測試用例test函數模擬一次請求存取的Controller或者service函數。
@SpringBootTest class DynamicTableNameTest { @Resource private StudentMapper studentMapper; @Test void test() { //執行資料操作之前設定月份(實際場景下該引數從請求引數中解析) MonthTableNameHandler.setData("202208"); studentMapper.selectById(1); //以id=2查詢student_202208這張表 //閱後即焚,將ThreadLocal當前請求執行緒的資料移除 MonthTableNameHandler.removeData(); } }
當我們執行這個單元測試用例的時候,我們發現控制檯列印出如下資訊,注意看SQL的部分,真的是去查詢student_202208這張表了,而不是student表。這說明我們的動態表名實現是成功的。
到此這篇關於SQL資料分表Mybatis Plus動態表名優方案的文章就介紹到這了,更多相關Mybatis Plus優化內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45