当前使用版本(必填,否则不予处理)

3.3.2

该问题是如何引起的?(确定最新版也有问题再提!!!)

/想使用databaseId做sql切换,通用sql不写databaseId标签,其他sql写了,但是加载时加载不写的,写了的被忽略不加载/ 其实是关于databaseID加载顺序引起的,内存只会维护安装文件顺序第一个被读到的sql,其他的均会被略过

重现步骤(如果有就写完整)

完整的情况是,两个xml的两段sql,一个是oracle版,不写databaseId,另一个是pgsql版的 写了databaseId = “pgsql”,如当前数据源是pgsql,mybatis会执行pgsql那段sql是正常的,但是mp不会,mp在加载xml文件时会根据接口的全限定名去对比,比如它先读到oracle的那段sql放进集合,在读到pgsql那段是发现集合内已经存在了,就跳过pgsql那段sql,所以当数据源为pgsql时,它执行的还是oracle那段sql,我的做法就是根据当前数据源类型对比sql片段的databaseId,动态的更新集合内的执行对象 (其实这个问题出在加载顺序上,如果它先加载pgsql的,那就会略过oracle的,结果就对了,但只是巧合),提示 * is ignored, because it exists, maybe from xml file,导致其还使用Oracle的sql,导致报错

报错信息

is ignored, because it exists, maybe from xml file

Comment From: 986510453

@hejiayangzh 最新版本是否还存在这个问题?

Comment From: hejaya

最新版本未测,公司也不让升级,我自己处理了

Comment From: huayanYu

你是如何处理的。?静态多数据源应该可以支持, 动态多数据源应该切换不了的吧。 mybatis原生就不是这么设计的。

@hehan-wang

Comment From: hejaya

就是单数据源测的,完整的情况是,两个xml的两段sql,一个是oracle版,不写databaseId,另一个是pgsql版的 写了databaseId = “pgsql”,如当前数据源是pgsql,mybatis会执行pgsql那段sql是正常的,但是mp不会,mp在加载xml文件时会根据接口的全限定名去对比,比如它先读到oracle的那段sql放进集合,在读到pgsql那段是发现集合内已经存在了,就跳过pgsql那段sql,所以当数据源为pgsql时,它执行的还是oracle那段sql,我的做法就是根据当前数据源类型对比sql片段的databaseId,动态的更新集合内的执行对象 (其实这个问题出在加载顺序上,如果它先加载pgsql的,那就会略过oracle的,结果就对了,但只是巧合)@huayanYu

Comment From: qmdx

to https://github.com/baomidou/dynamic-datasource-spring-boot-starter

Comment From: allengrit2211

版本3.4.3 1. com.baomidou.mybatisplus.core.MybatisConfiguration.addMappedStatement 类存储时将databaseId也作为 Map mappedStatements的key,避免相同mapper相同ID不能注册的问题, 2.对com.baomidou.mybatisplus.core.MybatisConfiguration.getMappedStatement 类获取MappedStatement对象时将id默认拼接 databaseId 以便可以获取对应databaseId下的mapper id

/**
 * MybatisPlus 加载 SQL 顺序:
 * <p> 1、加载 XML中的 SQL </p>
 * <p> 2、加载 SqlProvider 中的 SQL </p>
 * <p> 3、XmlSql 与 SqlProvider不能包含相同的 SQL </p>
 * <p>调整后的 SQL优先级:XmlSql > sqlProvider > CurdSql </p>
 */
@Override
public void addMappedStatement(MappedStatement ms) {
    String id = ms.getId() + ((ms.getDatabaseId() == null || ms.getDatabaseId().length() == 0) ? "" : "-" + ms.getDatabaseId());
    logger.debug("addMappedStatement: " + id);
    if (mappedStatements.containsKey(id)) {
        /*
         * 说明已加载了xml中的节点; 忽略mapper中的 SqlProvider 数据
         */
        logger.error("mapper[" + id + "] is ignored, because it exists, maybe from xml file");
        return;
    }
    mappedStatements.put(id, ms);
}


@Override
public MappedStatement getMappedStatement(String id) {
    String _id = id + ((databaseId == null || databaseId.length() == 0) ? "" : "-" + databaseId);
    if (mappedStatements.containsKey(_id)) {
        return this.getMappedStatement(_id, true);
    }
    return this.getMappedStatement(id, true);
}

Comment From: 1435646097

版本3.4.3

  1. com.baomidou.mybatisplus.core.MybatisConfiguration.addMappedStatement 类存储时将databaseId也作为 Map mappedStatements的key,避免相同mapper相同ID不能注册的问题, 2.对com.baomidou.mybatisplus.core.MybatisConfiguration.getMappedStatement 类获取MappedStatement对象时将id默认拼接 databaseId 以便可以获取对应databaseId下的mapper id /**

  2. MybatisPlus 加载 SQL 顺序:

  3. 1、加载 XML中的 SQL
  4. 2、加载 SqlProvider 中的 SQL
  5. 3、XmlSql 与 SqlProvider不能包含相同的 SQL
  6. 调整后的 SQL优先级:XmlSql > sqlProvider > CurdSql

/ @OverRide public void addMappedStatement(MappedStatement ms) { String id = ms.getId() + ((ms.getDatabaseId() == null || ms.getDatabaseId().length() == 0) ? "" : "-" + ms.getDatabaseId()); logger.debug("addMappedStatement: " + id); if (mappedStatements.containsKey(id)) { / * 说明已加载了xml中的节点; 忽略mapper中的 SqlProvider 数据 */ logger.error("mapper[" + id + "] is ignored, because it exists, maybe from xml file"); return; } mappedStatements.put(id, ms); } @OverRide public MappedStatement getMappedStatement(String id) { String _id = id + ((databaseId == null || databaseId.length() == 0) ? "" : "-" + databaseId); if (mappedStatements.containsKey(_id)) { return this.getMappedStatement(_id, true); } return this.getMappedStatement(id, true); }

您好,我适配的时候也遇到了该问题,想要重写addMappedStatement方法,但是重写好了,如何给他替换进去又成了一个问题,请问您的如何替换进去的呢?

Comment From: hejaya

MyBatis-Plus databaseId 不写,其他的不被加载

把这个类整个放进自己的项目就可以了 包名跟原来保持一致