Replacing MyBatis with MyBatis-Plus in a Spring Boot 3 Project That Includes Flowable

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

  1. MyBatis and MyBatis-Plus can coexist only in limited scenarios, typically where one acts as an internal dependency of a library like Flowable.
  2. org.mybatis.spring.annotation.MapperScan can be used in multiple configuration classes, each targeting distinct mapper interfaces.
  3. 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.
  4. Spring Boot’s auto-configuration provides flexibility: MybatisAutoConfiguration requires MybatisProperties to be present; with out the mybatis porperty block, it stays dormant, while MybatisPlusAutoConfiguration takes over using the mybatis-plus properties.

Tags: spring-boot MyBatis mybatis-plus Flowable migration

Posted on Sun, 25 Oct 2026 16:00:57 +0000 by chingwaah