MyBatis-Plus vs MyBatis-Flex: Which One Is Better?

This article compares MyBatis-Plus and MyBatis-Flex across eight dimensions—including design philosophy, development efficiency, query flexibility, performance, database support, advanced features, dependency weight, and community ecosystem—to help developers choose the most suitable persistence framework for their projects.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
MyBatis-Plus vs MyBatis-Flex: Which One Is Better?

MyBatis-Plus Overview

MyBatis‑Plus is an enhancement layer for MyBatis that adds a set of ready‑to‑use features without modifying MyBatis core. It is fully compatible with MyBatis.

Reduction of Boilerplate

In native MyBatis an insert requires a mapper interface, XML mapping file and an entity class. With MyBatis‑Plus defining an entity that extends BaseMapper and calling userMapper.insert(user) reduces the code by more than 60%.

Enhancement Mechanism

MyBatis‑Plus inserts custom logic into MyBatis’s interceptor chain via MybatisPlusInterceptor. The core execution chain of MyBatis is:

mapper.selectById(1L) → MapperProxy.invoke() → MapperMethod.execute() → DefaultSqlSession.selectOne() → CachingExecutor.query() → SimpleExecutor.doQuery() → StatementHandler.prepare() → ParameterHandler.setParameters() → ResultSetHandler.handleResultSets()

The interceptor composes a responsibility chain such as PaginationInnerInterceptor, OptimisticLockerInnerInterceptor, TenantLineInnerInterceptor.

Three steps are performed:

Startup scanning and injection – During Spring Boot auto‑configuration MybatisPlusAutoConfiguration scans all interfaces that extend BaseMapper, generates a proxy for each and registers CRUD MappedStatement objects via MybatisSqlInjector.

Dynamic proxy at method call – When baseMapper.insert(entity) is invoked, the proxy reads annotations such as @TableId and @TableField, assembles the full INSERT SQL and hands it to MyBatis.

Condition‑builder SQL assembly – AbstractWrapper and its subclasses ( QueryWrapper, UpdateWrapper) translate chained method calls into parameterised SQL fragments. Lambda expressions are parsed via SerializedLambda to obtain field names without hard‑coded strings.

Key Features

Zero‑SQL CRUD

public interface UserMapper extends BaseMapper<User> { }
User user = userMapper.selectById(1L);
List<User> users = userMapper.selectList(wrapper);
userMapper.insert(user);
userMapper.updateById(user);
userMapper.deleteById(1L);

LambdaQueryWrapper

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "张三")
       .gt(User::getAge, 18)
       .orderByDesc(User::getCreateTime);
List<User> users = userMapper.selectList(wrapper);

Physical pagination

@GetMapping("/list")
public IPage<User> list(Page<User> page) {
    return userService.page(page); // SELECT * FROM user LIMIT ...
}

Optimistic lock

@Version
private Integer version;

Performance Concerns

Heavy dependencies on Spring, MyBatis‑Spring and several third‑party libraries.

CRUD operations rely on reflection to scan entity annotations at runtime, which adds overhead in large‑batch or high‑concurrency scenarios.

MyBatis-Flex Overview

Design Philosophy

MyBatis‑Flex is a community‑driven enhancement that keeps only MyBatis as a dependency and focuses on performance rather than feature bloat.

Mechanism without Interceptors

Flex avoids MyBatis’s interceptor mechanism. SQL strings are built directly by a SqlProvider architecture.

During compilation an Annotation Processing Tool (APT) scans entities annotated with @Table and generates constant classes that map column names. At runtime the framework reads these generated classes, eliminating reflection.

Native Multi‑Table Join

QueryWrapper query = QueryWrapper.create()
    .select(ACCOUNT.ID, ACCOUNT.USER_NAME, ORDER.AMOUNT.sum())
    .from(ACCOUNT)
    .leftJoin(ORDER).on(ACCOUNT.ID.eq(ORDER.USER_ID))
    .groupBy(ACCOUNT.ID);
List<AccountVO> results = accountMapper.selectListByQuery(query);

The chainable API provides type‑safe, IDE‑friendly multi‑table queries without XML.

Dynamic Table Names & Fields

Db.update("book_store_" + orgCode)
    .set("source_code", clashVal)
    .where("content_id = ?", channelId);

No XML or string concatenation; the code reads like ordinary Java.

Db+Row Utility

The Db+Row tool enables CRUD and pagination without defining entity classes, useful for rapid prototyping.

Eight‑Dimension Comparison

1. Core Design & Mechanism

MyBatis‑Plus – Non‑intrusive enhancement via MyBatis interceptor chain; dynamic proxy and reflection at runtime; depends on Spring and other libraries.

MyBatis‑Flex – Pure MyBatis core; compile‑time APT generates column constants; builds final SQL strings directly; no interceptor involvement.

2. Development Efficiency

MyBatis‑Plus – Extremely easy integration, mature ecosystem, abundant Chinese documentation, code generator, Lambda wrapper.

MyBatis‑Flex – Similar BaseMapper inheritance and chainable queries, but fewer Chinese resources; requires deeper source‑code reading.

3. Query Flexibility

MyBatis‑Plus – Elegant single‑table Wrapper, limited multi‑table join support; often falls back to XML or third‑party tools.

MyBatis‑Flex – Native, type‑safe support for left/right/inner joins, UNION ALL, sub‑queries, over 110 SQL functions, dynamic tables, and schemas.

4. Performance (querying 10,000 records)

MyBatis‑Plus – Moderate performance; runtime interceptor and reflection add overhead, especially in batch or complex queries.

MyBatis‑Flex – 5‑10× faster; near‑native MyBatis speed because it eliminates interceptor and runtime SQL parsing.

5. Database & Dialect Support

MyBatis‑Plus – Good support for mainstream databases (MySQL, PostgreSQL, Oracle, SQL Server); slower adoption of Chinese‑domestic databases.

MyBatis‑Flex – Supports >20 domestic databases (e.g., 达梦, 人大金仓, 华为高斯) in addition to mainstream ones.

6. Advanced Feature Completeness

MyBatis‑Plus – Rich features (primary‑key strategies, logical delete, optimistic lock, multi‑tenant, data permission, auto‑fill, code generator). Some advanced features require paid plugins.

MyBatis‑Flex – Free, open‑source equivalents for multi‑primary‑key, logical delete, optimistic lock, data fill, data masking, multi‑tenant, plus Db+Row.

7. Dependency Granularity

MyBatis‑Plus – Relatively heavy; pulls in spring‑tx, mybatis‑spring, and several third‑party libs.

MyBatis‑Flex – Extremely lightweight; only MyBatis itself.

8. Community & Outlook

MyBatis‑Plus – Over 15k GitHub stars, widely adopted in Chinese enterprises, active community, stable releases.

MyBatis‑Flex – Newer but fast‑moving; recent releases support Spring Boot 4, modern annotations, and show strong developer activity.

Selection Guidance

Choose MyBatis‑Plus when the project requires a proven, stable solution, rapid development of simple single‑table CRUD, or when the team already invests heavily in its ecosystem.

Choose MyBatis‑Flex for complex reporting or analytics that need frequent multi‑table joins, high‑concurrency micro‑services, multi‑tenant or dynamic‑schema scenarios, or projects targeting domestic databases with specialized dialects.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaPerformanceORMMyBatis-PlusComparisonMyBatis-Flex
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.