App下載

mybatis-plus動(dòng)態(tài)表名的具體實(shí)現(xiàn)過(guò)程以及實(shí)現(xiàn)原理

猿友 2021-07-17 09:56:33 瀏覽數(shù) (5777)
反饋

業(yè)務(wù)上有這樣的需求,在存儲(chǔ)數(shù)據(jù)的時(shí)候會(huì)根據(jù)某一個(gè)字段動(dòng)態(tài)的選擇數(shù)據(jù)要存儲(chǔ)的表。本篇文章將會(huì)為您詳細(xì)介紹關(guān)于 mybatis-plus 動(dòng)態(tài)表名的具體實(shí)現(xiàn)過(guò)程以及實(shí)現(xiàn)原理,以下是詳情內(nèi)容。

背景

在分表的背景下,有時(shí)候查詢數(shù)據(jù)的時(shí)候需要跨表查詢,那此時(shí)就需要MP在解析的時(shí)候,能夠很好的自適應(yīng)表格名稱

實(shí)現(xiàn)

MP中是通過(guò)PaginationInterceptor(分頁(yè)插件)完成動(dòng)態(tài)表名解析的,配置如下:

數(shù)據(jù)庫(kù)中表

依賴

<dependency>
 <groupId>com.baomidou</groupId>
 <artifactId>mybatis-plus-boot-starter</artifactId>
 <version>3.3.1.tmp</version>
</dependency>

配置類

package com.huanchuang.common.config;
 
import com.baomidou.mybatisplus.extension.parsers.DynamicTableNameParser;
import com.baomidou.mybatisplus.extension.parsers.ITableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import java.util.Collections;
import java.util.HashMap;
 
/**
 * @Package: com.huanchuang.common.config
 * @Description: <mybatis-plush配置類>
 * @Author: MILLA
 * @CreateDate: 2020/09/04 14:42
 * @UpdateUser: MILLA
 * @UpdateDate: 2020/09/04 14:42
 * @UpdateRemark: <>
 * @Version: 1.0
 */
@Configuration
@MapperScan("com.huanchuang.ext.mapper**")
@ConditionalOnProperty(prefix = "spring.config", name = "enableMybatisPlusDynamicTable", havingValue = "true")
public class MybatisPlusDynamicTableConfig {
 
 private static final String DYNAMIC_TABLE_PRE = "common_user";
 
 /**
  * mybatis-plus分頁(yè)插件
  */
 @Bean
 public PaginationInterceptor paginationInterceptor() {
  PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
  // 設(shè)置請(qǐng)求的頁(yè)面大于最大頁(yè)后操作, true調(diào)回到首頁(yè),false 繼續(xù)請(qǐng)求 默認(rèn)false
  paginationInterceptor.setOverflow(false);
  // 設(shè)置最大單頁(yè)限制數(shù)量,默認(rèn) 500 條,-1 不受限制
  paginationInterceptor.setLimit(500);
//  // 開(kāi)啟 count 的 join 優(yōu)化,只針對(duì)部分 left join
  paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
  DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
  dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>(2) {{
   //動(dòng)態(tài)表規(guī)則-生成自己需要的動(dòng)態(tài)表名
   put(DYNAMIC_TABLE_PRE, (metaObject, sql, tableName) -> DynamicTableTreadLocal.INSTANCE.getTableName());
  }});
  paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
  return paginationInterceptor;
 }
}

動(dòng)態(tài)表名存儲(chǔ)類

package com.huanchuang.common.config;
 
/**
 * @Package: com.huanchuang.common.config
 * @Description: <動(dòng)態(tài)表格存儲(chǔ)類>
 * @Author: MILLA
 * @CreateDate: 2020/09/04 14:42
 * @UpdateUser: MILLA
 * @UpdateDate: 2020/09/04 14:42
 * @UpdateRemark: <>
 * @Version: 1.0
 */
public enum DynamicTableTreadLocal {
 INSTANCE;
 private ThreadLocal<String> tableName = new ThreadLocal<>();
 
 public String getTableName() {
  return tableName.get();
 }
 
 public void setTableName(String tableName) {
  this.tableName.set(tableName);
 }
 
 public void remove() {
  tableName.remove();
 }
 
}

使用

 private void select(int year) {
 
   DynamicTableTreadLocal.INSTANCE.setTableName("user_" + year);
   LambdaQueryWrapper<SparkDownSample> wrapper = Wrappers.lambdaQuery(User.class);
   List<User> userList = userMapper.list(wrapper )
 
 }
@Data
public class User {
 
 private Long id;
 
 private String userName;
 
 private String address;
 
 private char sex;
 
 private Byte age;
 
}

原理

原理01

2021040411252177

2021040411252178

2021040411252179

2021040411252180

2021040411252181

2021040411252182

2021040411252183

2021040411252184

以mybatis的query方法作為入口通過(guò)動(dòng)態(tài)代理執(zhí)行到配置的分頁(yè)插件通過(guò)分頁(yè)插件進(jìn)行sql解析根據(jù)分頁(yè)插件中配置的tableNameHandler進(jìn)行目標(biāo)表格的替換最后形成一個(gè)可執(zhí)行sql,執(zhí)行查詢

本篇關(guān)于 mybatis-plus 動(dòng)態(tài)表名的具體實(shí)現(xiàn)過(guò)程以及實(shí)現(xiàn)原理的內(nèi)容就介紹到此技術(shù)了,想要了解更多相關(guān) mybatis-plus 動(dòng)態(tài)表名的其他詳細(xì)內(nèi)容請(qǐng)搜索W3Cschool以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持!


1 人點(diǎn)贊