There is a common scenario where a project built solely on MyBatis must later incorporate MyBatis-Plus. Even though the goal appears to be "coexistence," MyBatis-Plus is effectively a superset of MyBatis, so the more practical path is switching to MyBatis-Plus and eliminating MyBatis’s dedicated configuration. The steps below describe how to handle this migration when the application also uses Flowable (which internally depends on MyBatis).
Environment
- Spring Boot 3.4.4
- MyBatis-Plus
mybatis-plus-spring-boot3-starter - Flowable
flowable-spring-boot-starter-process
Adjusting POM files
Two POM files need modificasion: a shared dependency POM and the module-specific POM that includes Flowable.
Shared POM
Exclude MyBatis artifacts from the original starter and introduce the MyBatis-Plus starter while keeping pagehelper compatible:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
After this change, both MyBatis and MyBatis-Plus auto-configuration classes remain on the classpath, but only one will ultimately activate based on property presence.
Flowable module POM
Manage the MyBatis version explicitly and exclude the transitive MyBatis dependency coming from Flowable:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-process</artifactId>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
The explicit mybatis dependency must match the version expected by MyBatis-Plus to avoid conflicts.
Removing the old MyBatis configuration class
Delete (or comment out) any manual SqlSessionFactory configuration. The auto-configuration from MyBatis-Plus will handle session factory creation. Keeping a legacy configuration class may interfere with the desired behavior.
YAML configuration
Move previous MyBatis properties into the mybatis-plus namespace:
mybatis-plus:
type-aliases-package: com.redot.hdp.**.mapper,com.redotxxx.flowable.**.plusmapper
mapperLocations: classpath*:mapper/**/*Mapper.xml
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
Once the mybatis property prefix disappears, the standard MyBatis auto-configuration backs off, leaving only MyBatis-Plus active.
MyBatis-Plus configuration class
Create an auto-configuration that runs before MybatisPlusAutoConfiguration and scans mapper interfaces marked with @Mapper:
@AutoConfiguration(before = MybatisPlusAutoConfiguration.class)
@MapperScan(value = {"com.redotxxx.flowable"}, annotationClass = Mapper.class)
public class MybatisPlusAutoConfig {
}
The main application class continues to scan the original MyBatis mappers:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class})
@MapperScan(value = {"com.redotxxx.**.mapper"})
@ComponentScan(value = {"com.redotxxx"})
public class HdpApplication {
public static void main(String[] args) {
SpringApplication.run(HdpApplication.class, args);
}
}
Although it is possible to merge both @MapperScan definitions into a single configuration, keeping them separate is acceptable. The DataSource is configured manually, so DataSourceAutoConfiguration is excluded.
Key takeaways
- MyBatis and MyBatis-Plus can coexist only in limited scenarios, typically where one acts as an internal dependency of a library like Flowable.
org.mybatis.spring.annotation.MapperScancan be used in multiple configuration classes, each targeting distinct mapper interfaces.- When MyBatis-specific YAML properties (e.g.,
mybatis.*) are removed, the MyBatis auto-configuration does not activate. In this setup, only MyBatis-Plus is truly operational. - Spring Boot’s auto-configuration provides flexibility:
MybatisAutoConfigurationrequiresMybatisPropertiesto be present; with out themybatisporperty block, it stays dormant, whileMybatisPlusAutoConfigurationtakes over using themybatis-plusproperties.