Using MyBatis-Plus (MP) in Java Backend Development: Advantages, Disadvantages, and Best Practices

This article evaluates MyBatis-Plus (MP) for Java backend development, highlighting its convenient CRUD shortcuts, code examples, maintenance challenges, magic value pitfalls, and recommended practices such as using LambdaQueryWrapper, pagination, and avoiding overly complex SQL within MP.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
Using MyBatis-Plus (MP) in Java Backend Development: Advantages, Disadvantages, and Best Practices

Hello everyone, I'm Lei.

Below are some promotional links to Java architecture video courses and a Flowable 400-lecture bundle, which are not the focus of this technical discussion.

Pros and Cons of MyBatis-Plus (MP)

MP has sparked debate since its inception. Users appreciate its ability to automatically concatenate SQL via functions, eliminating the need for XML mapping and dramatically speeding up simple CRUD operations.

However, critics point out that MP can intrude into the Service layer, leading to poor maintainability, low readability, tight coupling, and difficulty optimizing SQL.

Advantages

Simple Operations

Typical CRUD can be performed with one‑line mapper calls such as:

nodeMapper.selectById(1);
nodeMapper.deleteById(2);
nodeMapper.updateById(new Node());
nodeMapper.insert(new Node());

These methods, however, often select all columns (SELECT *), which is a maintenance concern.

To avoid this, developers can use the QueryWrapper to specify fields:

nodeMapper.selectOne(new QueryWrapper<Node>().eq("id",1).select("id"));

Using LambdaQueryWrapper further improves type safety and readability:

Node node = nodeMapper.selectOne(new LambdaQueryWrapper<Node>().eq(Node::getId,1).select(Node::getId));

Replacing magic strings with enums or constant classes is recommended to enhance maintainability.

Pagination is straightforward with MP:

// Build query conditions
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UserInfo::getAge,20);
// Create pagination object
Page<UserInfo> queryPage = new Page<>(page,limit);
// Execute paged query
IPage<UserInfo> iPage = userInfoMapper.selectPage(queryPage, queryWrapper);
Long total = iPage.getTotal();
List<UserInfo> list = iPage.getRecords();

Disadvantages

MP struggles with complex SQL such as multi‑table joins, aggregate functions, or custom SELECT clauses. Attempting to write raw SQL like SELECT SUM(price_count) FROM bla_order_data LIMIT 100 within MP often fails to compile.

Developers may resort to @Select annotations with ${ew.customSqlSegment}, but this defeats MP's purpose and reintroduces XML mapping.

Furthermore, reliance on auto‑generated methods like selectById can hide performance issues and make future schema changes error‑prone.

Simple Summary

MP is suitable for simple single‑table queries but should be avoided for complex SQL scenarios.

Recommendations:

Isolate MP queries in a dedicated package to avoid Service‑layer intrusion.

Prefer LambdaQueryWrapper for better maintainability.

Leverage MP's built‑in primary‑key generation and pagination plugins.

Avoid using generic methods like selectById for production code.

Use MP for straightforward CRUD; switch to custom SQL or MyBatis XML for complex operations.

JavaSQLORMPaginationLambdaQueryWrapperMyBatis-Plus
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

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.