業(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)過程以及實(shí)現(xiàn)原理,以下是詳情內(nèi)容。
背景
在分表的背景下,有時(shí)候查詢數(shù)據(jù)的時(shí)候需要跨表查詢,那此時(shí)就需要MP在解析的時(shí)候,能夠很好的自適應(yīng)表格名稱
實(shí)現(xiàn)
MP中是通過PaginationInterceptor(分頁插件)完成動(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分頁插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 設(shè)置請(qǐng)求的頁面大于最大頁后操作, true調(diào)回到首頁,false 繼續(xù)請(qǐng)求 默認(rèn)false
paginationInterceptor.setOverflow(false);
// 設(shè)置最大單頁限制數(shù)量,默認(rèn) 500 條,-1 不受限制
paginationInterceptor.setLimit(500);
// // 開啟 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;
}
原理
以mybatis的query方法作為入口通過動(dòng)態(tài)代理執(zhí)行到配置的分頁插件通過分頁插件進(jìn)行sql解析根據(jù)分頁插件中配置的tableNameHandler進(jìn)行目標(biāo)表格的替換最后形成一個(gè)可執(zhí)行sql,執(zhí)行查詢
本篇關(guān)于 mybatis-plus 動(dòng)態(tài)表名的具體實(shí)現(xiàn)過程以及實(shí)現(xiàn)原理的內(nèi)容就介紹到此技術(shù)了,想要了解更多相關(guān) mybatis-plus 動(dòng)態(tài)表名的其他詳細(xì)內(nèi)容請(qǐng)搜索W3Cschool以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持!