mybatis項(xiàng)目實(shí)現(xiàn)動(dòng)態(tài)表名的三種方法
實(shí)現(xiàn)動(dòng)態(tài)表名是個(gè)很常見的需求,網(wǎng)上也有很多解決方法,這邊總結(jié)了三種實(shí)現(xiàn)方式。
一、手動(dòng)給每個(gè)方法加個(gè)表名的變量
缺點(diǎn)很明顯,侵入性大,不方便,不推薦
二、mybatis插件機(jī)制攔截sql替換表名實(shí)現(xiàn)動(dòng)態(tài)表名
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
/**
* mybatis插件實(shí)現(xiàn)動(dòng)態(tài)表名,可以攔截器新增、編輯、刪除、查詢等
*/
@Component
@Intercepts({
@Signature(type = StatementHandler.class, method = "prepare", args = {
Connection.class, Integer.class})})
public class ReplaceTablePlugin implements Interceptor {
private static final Logger LOG = LoggerFactory.getLogger(ReplaceTablePlugin.class);
private final static Map<String, String> TABLE_MAP = new LinkedHashMap<>();
/**
* 需要替換的表(替換前的表名和替換后的表名)
*/
static {
TABLE_MAP.put("t_user", "t_user_20220101");
TABLE_MAP.put("t_org", "t_org_20220202");
}
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = realTarget(invocation.getTarget());
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
doTable(statementHandler, metaObject);
return invocation.proceed();
}
private void doTable(StatementHandler handler, MetaObject metaStatementHandler) throws ClassNotFoundException {
BoundSql boundSql = handler.getBoundSql();
String originalSql = boundSql.getSql();
if (originalSql != null && !originalSql.equals("")) {
LOG.info("攔截前的sql:{}", originalSql);
if (isReplaceTableName(originalSql)) {
for (Map.Entry<String, String> entry : TABLE_MAP.entrySet()) {
originalSql = originalSql.replace(entry.getKey(), entry.getValue());
}
LOG.info("攔截后的sql:{}", originalSql);
metaStatementHandler.setValue("delegate.boundSql.sql", originalSql);
}
}
}
private boolean isReplaceTableName(String sql) {
for (String tableName : TABLE_MAP.keySet()) {
if (sql.contains(tableName)) {
return true;
}
}
return false;
}
@Override
public Object plugin(Object target) {
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
}
return target;
}
@Override
public void setProperties(Properties properties) {
}
/**
* Obtain real processing objects, possibly multi-layer agents
*
* @param target
* @param <T>
* @return
*/
public static <T> T realTarget(Object target) {
if (Proxy.isProxyClass(target.getClass())) {
MetaObject metaObject = SystemMetaObject.forObject(target);
return realTarget(metaObject.getValue("h.target"));
}
return (T) target;
}
}三、mybatis-plus的DynamicTableNameInnerInterceptor實(shí)現(xiàn)
3.1引入mybatis-plus的pom jar包依賴
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.5.2</version>
</dependency>3.2 實(shí)現(xiàn)的配置類
import java.util.Map;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.redis.core.RedisTemplate;
/**
*
* mybatis-plus實(shí)現(xiàn)動(dòng)態(tài)替換表名
*/
@MapperScan("com.xiaweiyi8080.dal.mapper")
@ComponentScan({"com.xiaweiyi8080.dal.manager"})
@Slf4j
public class MyBatisPlusConfiguration {
@Autowired
private RedisTemplate redisTemplate;
// 配置文件里配置的哪些表需要?jiǎng)討B(tài)表名
@Value("${xxxxx.tableName:}")
private String dynamicTableName;
@Bean
public MybatisPlusInterceptor dynamicTableNameInterceptor() {
log.info("------拿到的dynamicTableName={}", dynamicTableName);
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
// 獲取參數(shù)方法
Map<String, Object> paramMap = RequestDataHelper.getRequestData();
if (CollectionUtil.isNotEmpty(paramMap)) {
paramMap.forEach((k, v) -> log.info(k + "----" + v));
}
if (StringUtils.isNotBlank(dynamicTableName) && dynamicTableName.contains(tableName)) {
log.info("------替換前表名={}", tableName);
String suffix = "_20220101";
tableName += suffix;
log.info("------替換后表名={}", tableName);
}
return tableName;
});
interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
return interceptor;
}
}到此這篇關(guān)于mybatis項(xiàng)目實(shí)現(xiàn)動(dòng)態(tài)表名的三種方法的文章就介紹到這了,更多相關(guān)mybatis 動(dòng)態(tài)表名內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot Mybatis批量插入Oracle數(shù)據(jù)庫(kù)數(shù)據(jù)
這篇文章主要介紹了SpringBoot Mybatis批量插入Oracle數(shù)據(jù)庫(kù)數(shù)據(jù),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08
一文詳解Java如何實(shí)現(xiàn)將PowerPoint轉(zhuǎn)換為HTML
在日常開發(fā)和業(yè)務(wù)場(chǎng)景中,我們經(jīng)常會(huì)遇到將PowerPoint(PPT)演示文稿轉(zhuǎn)換為HTML的需求,本文將深入探討如何使用Java將PowerPoint文檔轉(zhuǎn)換為HTML,包括整體轉(zhuǎn)換和指定幻燈片轉(zhuǎn)換兩種場(chǎng)景,希望對(duì)大家有所幫助2025-12-12
如何對(duì)quartz定時(shí)任務(wù)設(shè)置結(jié)束時(shí)間
這篇文章主要介紹了如何對(duì)quartz定時(shí)任務(wù)設(shè)置結(jié)束時(shí)間問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
java基于RMI遠(yuǎn)程過(guò)程調(diào)用詳解
這篇文章主要為大家詳細(xì)介紹了java基于RMI遠(yuǎn)程過(guò)程調(diào)用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
Spring Cloud項(xiàng)目前后端分離跨域的操作
這篇文章主要介紹了Spring Cloud項(xiàng)目前后端分離跨域的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06

