mybatis-plus动态设置 @TableName的schema属性

2,692 阅读1分钟

背景

其实就是跨库操作,我们没有做动态数据源~
a项目用的是a库,但是我想操作b库的数据,这时候就只能通过设置@TableName的schema来进行操作了

实现

1、实体类 Test.java

package xxxxxxxxxxx;


import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import xxxxxxxxxx.DynamicTable;

import java.io.Serializable;
import java.util.Date;

/**
 * @author Levan
 * @date 2022-05
 */
@Getter
@Setter
@Accessors(chain = true)
@TableName(value = "table_a", schema = DynamicTable.schema_b)
public class Test implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id")
    private String id;

    @TableField(value = "code")
    private String code;

    @TableField(value = "number")
    private String number;

}

配置 DynamicTable.java

package xxxxxxxxxxxx;

import com.baomidou.mybatisplus.annotation.TableName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;
import xxxx.Test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;


@Component
public class DynamicTable implements InstantiationAwareBeanPostProcessor {
    private static final Logger log = LoggerFactory.getLogger(DynamicTable.class);

    @Value("${spring.profiles.active}")
    public String environment;

    public static final String schema_a = "schema_a";
    public static final String schema_b = "schema_b";
    //只初始化一次
    private static  boolean isOk = false;


    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (!isOk){
            set(Test.class);
            isOk = true;
        }
        return null;
    }

    private void set(Class<?>... classs){
        for (Class<?> aClass : classs) {
            TableName table = aClass.getAnnotation(TableName.class);
            //获取代理处理器
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(table);
            Field values;
            try {
                // 过去私有 memberValues 属性
                values = invocationHandler.getClass().getDeclaredField("memberValues");
                values.setAccessible(true);

                // 获取实例的属性map
                Map<String, Object> memberValues =(Map<String, Object>) values.get(invocationHandler);
                // 修改属性值
                String schema = "dev".equals(environment) ? schema_a: schema_b;
                memberValues.put("schema", schema);

                log.info(String.format("当前环境为: %s,设置 %s 的schema为:%s ", environment,  aClass.getSimpleName(), schema));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}