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; }
如上,数据库的表名为 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的生命周期自己设置。
用这个方法可以在运行时根据配置文件动态的修改注解中的值。
生来奔走万山中,踏尽崎岖路自通