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.
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
