問題:
最近碰到一個需求,使用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的生命周期自己設置。
用這個方法可以在運行時根據配置文件動態的修改注解中的值。