mybatisplus运行时修改@TableName注解的schema值

问题:

最近碰到一个需求,使用mybatisplus时,因为权限原因,某张数据表需要用只读用户来读取,也就是说要指定schema,开发环境和测试环境的schema不一致,但是注解中的schema是写死的,不能根据配置文件来动态设置

 其他的环境不贴了,实体类如下:

@Data
@TableName(value = "RULE_BASIC_INFO",schema = "DEV_USER")
@ApiModel(value = "规则对象 RULE_BASIC_INFO")
public class XfRule implements Serializable{

    @TableId(type = IdType.AUTO)
    @ApiModelProperty(value = "主键ID", hidden = true)
    private Integer ruleId;

    @ApiModelProperty(value = "规则名称")
    private String ruleName;

}
View Code

如上,数据库的表名为 RULE_BASIC_INFO,开发环境需要用DEV_USER来读取数据,测试环境需要用TEST_USER用户来读取数据

 

解决方法:

新建一个DynamicUser类如下:

 

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

    @Value("${znzj.dapschema:DAP_USER}")
    public String dapschema;

    private static boolean isFirst = true;

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        //只初始化一次
        if (isFirst) {
            //设置数据库用户
            this.setSchema();
            isFirst=false;
        }
        return null;
    }

    private void setSchema(){
//        if("ctyun-online".equals(environment)){
//            log.info("当前环境为:"+environment+" 使用默认user为DAP_USER");
//            return;
//        }
        log.info("当前dapscheam为"+dapschema);
        Map<String, Object> memberValues = this.getMemberValues(XfRule.class, TableName.class);
        if(memberValues!=null){
            memberValues.put("schema",dapschema);
//            log.info("当前环境为:"+environment+" 设置user为YCDAP_USER");
        }
    }


    /**
     * 获取类注解属性
     * @param source 类
     * @param annotationClass 注解
     * @return
     */
    private Map<String, Object> getMemberValues(Class source,Class annotationClass){
        Annotation annotation = source.getAnnotation(annotationClass);
        InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
        Field values = null;
        try {
            values = invocationHandler.getClass().getDeclaredField("memberValues");
            values.setAccessible(true);
            Map<String, Object> memberValues =(Map<String, Object>) values.get(invocationHandler);
            return memberValues;
        } catch (Exception e) {
            log.error("注解反射出错",e);
        }
        return null;
    }
}

  

 

 

注意事项:

不一定要实现InstantiationAwareBeanPostProcessor 接口,然后写代码逻辑,但重要的是必须要在mybatisplus的com.baomidou.mybatisplus.core.metadata.TableInfoHelper.initTableName方法执行之前将schema的值设置到memberValues里,具体的代码位置及时机可以参考spring bean的生命周期自己设置。

 

用这个方法可以在运行时根据配置文件动态的修改注解中的值。

posted @ 2021-05-07 17:24  万界漂泊者  阅读(6363)  评论(5编辑  收藏  举报