mybatis-plus动态表名 DynamicTableNameInnerInterceptor【一个非常简单的例子】

发布于:2024-07-02 ⋅ 阅读:(47) ⋅ 点赞:(0)

1前言

3.4.3.2 作废setTableNameHandlerMap方式,这里不做赘述

		// 3.4.3.2 作废该方式
		// dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);

官网地址https://baomidou.com/plugins/dynamic-table-name/
官网案例源码https://gitee.com/baomidou/mybatis-plus-samples/tree/master/mybatis-plus-sample-dynamic-tablename
官网给的案例不是非常适合项目中处理,这里简单介绍一下我自己的想法

2 增加maven依赖

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.6</version>
        </dependency>

3 核心就下面的3个文件

通过本地线程来存储要操作的表名字,等到sql要执行的时候再替换为需要执行的表名字来实现动态表名

TableDto

package cn.fox.mydemo.domain.dto;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class TableDto {
    /**
     *  表名字前缀
     */
    private String tableNamePrefix;
    /**
     * 表名字全称
     */
    private String tableName;
}

TableStrThreadLocal 本地线程

package cn.fox.mydemo.domain.dto;

import com.baomidou.mybatisplus.annotation.TableName;

/**
 * 表名线程变量
 */
public class TableStrThreadLocal {
    private static final ThreadLocal<TableDto> TABLE_STR_TL = new ThreadLocal<>();

    /**
     * 设置
     * @param clazz class
     * @param tableNameSuffix 表名字后缀
     */
    public static void set(Class<?> clazz, String tableNameSuffix) {
        TableDto tableDto = new TableDto();
        TableName tableNamePrefix = clazz.getAnnotation(TableName.class);
        tableDto.setTableNamePrefix(tableNamePrefix.value());
        tableDto.setTableName(tableNamePrefix.value() + tableNameSuffix);
        TABLE_STR_TL.set(tableDto);
    }

    /**
     * 获取
     * @return String
     */
    public static TableDto get(){
        if(TABLE_STR_TL.get() == null){
            TABLE_STR_TL.set(new TableDto());
        }
        return TABLE_STR_TL.get();
    }

    /**
     * 删除
     */
    public static void remove() {
        TABLE_STR_TL.remove();
    }
}

Configuration

package cn.fox.mydemo.config;

import cn.fox.mydemo.domain.dto.TableDto;
import cn.fox.mydemo.domain.dto.TableStrThreadLocal;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration(proxyBeanMethods = false)
public class MybatisAutoConfiguration implements WebMvcConfigurer {

	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		// 分页插件, 对于单一数据库类型来说,都建议配置该值,避免每次分页都去抓取数据库类型
		interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

		DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();


		dynamicTableNameInnerInterceptor.setTableNameHandler((sql, originalTableName) -> {
			TableDto tableDto = TableStrThreadLocal.get();
			// 如果缓存里面的表名字前缀和固定值相等,就取缓存里面的表名字全称
			if("user_".equals(tableDto.getTableNamePrefix())){
				return tableDto.getTableName();
			}
			// 没有匹配到就取原来的表名字
			return originalTableName;
		});
		// 3.4.3.2 作废该方式
		// dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);
		interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
		return interceptor;
	}


}

4 测试

新建两张表,加两条数据

CREATE TABLE `user_1` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `name` varchar(255) DEFAULT NULL COMMENT '名字',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


CREATE TABLE `user_2` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `name` varchar(255) DEFAULT NULL COMMENT '名字',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `my_test`.`user_1` (`id`, `name`, `age`) VALUES (1, '用户1', 18);
INSERT INTO `my_test`.`user_1` (`id`, `name`, `age`) VALUES (1, '用户2', 35);

user实体

package cn.fox.mydemo.domain.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;

@Getter
@Setter
@TableName("user_")
public class User implements Serializable {
    private static final long serialVersionUID = 132777406752307410L;
    /**
     * 主键id
     */
    private Integer id;
    /**
     * 名字
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
}

mapper

package cn.fox.mydemo.mapper;

import cn.fox.mydemo.domain.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

IUserService

package cn.fox.mydemo.service;

import cn.fox.mydemo.domain.entity.User;
import com.baomidou.mybatisplus.extension.service.IService;

public interface IUserService extends IService<User> {

}

UserServiceImpl

package cn.fox.mydemo.service.impl;

import cn.fox.mydemo.domain.entity.User;
import cn.fox.mydemo.mapper.UserMapper;
import cn.fox.mydemo.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

}

测试

package cn.fox.mydemo;

import cn.fox.mydemo.domain.dto.TableStrThreadLocal;
import cn.fox.mydemo.domain.entity.User;
import cn.fox.mydemo.service.IUserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
public class TableDemo {
    @Autowired
    private IUserService userService;

    @Test
    public void test() {
        TableStrThreadLocal.set(User.class, "1");
        List<User> list1 = userService.list();
        System.out.println(list1);


        TableStrThreadLocal.set(User.class, "2");
        List<User> list2 = userService.list();
        System.out.println(list2);
    }
}

TableStrThreadLocal.set(User.class, “1”);
第一个参数是实体class,第二个参数是要动态调用的表名字后缀,在mybatisplsh调用之前设置一下就行。


网站公告

今日签到

点亮在社区的每一天
去签到