Unlock MyBatis-Plus: From Zero-Code CRUD to Advanced Plugins
This article introduces MyBatis-Plus as a zero‑intrusion enhancement to MyBatis, explains its core values of convenience, safety, and compatibility, details CRUD methods, condition builders, plugin mechanisms, and best‑practice guidelines for building efficient, secure backend services.
1. MyBatis-Plus Overview: More Than an Enhancement
MyBatis-Plus combines MyBatis with a Swiss‑army‑knife‑style API and a safety lock, offering zero‑intrusion single‑table operations while preserving native MyBatis features.
Its three core values are:
Swiss‑army‑knife convenience : Replace XML configuration with Lambda expressions for complex operations with minimal code.
Safety‑lock security : Interceptors prevent dangerous statements like “delete from table”, eliminating accidental data loss.
Zero‑intrusion compatibility : No changes to existing MyBatis code are required; legacy projects can migrate smoothly.
2. Core Features: An All‑Purpose Toolbox for Single‑Table CRUD
All CRUD methods are exposed through the BaseMapper interface, requiring no manual implementation.
2.1 Basic CRUD – Zero‑Code Operations
BaseMapper provides methods such as: int insert(T entity) – inserts a record, ignoring null fields. boolean insertOrUpdate(T entity) – inserts or updates based on primary key. int deleteById(Serializable id) – deletes a record by primary key. int deleteByIds(Collection<?> idList) – batch delete with size control. int updateById(T entity) – updates by primary key, ignoring null fields. T selectById(Serializable id) – query by primary key. List<T> selectList(Wrapper<T> queryWrapper) – conditional batch query (beware of full‑table scans when wrapper is null).
2.2 Condition Builder – Elegant Complex Queries
The condition builder is the “soul” of MyBatis‑Plus, offering four main wrappers:
QueryWrapper : basic string‑based conditions, e.g. eq("name","张三").
LambdaQueryWrapper : Lambda‑based, type‑safe conditions, e.g. eq(User::getName,"张三"). Recommended for most cases.
UpdateWrapper / LambdaUpdateWrapper : build update conditions with dynamic set values.
Using LambdaQueryWrapper prevents field‑spelling errors and enables compile‑time checks:
// ❌ Not recommended: string‑based conditions
QueryWrapper<User> qw = new QueryWrapper<>();
qw.eq("name","张三").gt("age",18);
// ✅ Recommended: Lambda conditions
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.eq(User::getName,"张三").gt(User::getAge,18);Advantages include compile‑time field validation, automatic refactoring updates, and clearer code.
2.3 Plugin Suite – Extensible “Universal Interface”
MyBatis‑Plus uses MybatisPlusInterceptor to provide plugins such as: PaginationInnerInterceptor – automatic pagination (must be configured). BlockAttackInnerInterceptor – blocks full‑table update/delete operations. OptimisticLockerInnerInterceptor – optimistic locking via version fields. TenantLineInnerInterceptor – multi‑tenant data isolation. IllegalSQLInnerInterceptor – enforces SQL best practices (e.g., disallow SELECT *).
3. Best Practices for Efficient and Safe MP Code
3.1 Prefer Lambda Query Wrappers
Never use string‑based conditions; LambdaQueryWrapper catches missing fields and type mismatches at compile time.
3.2 Conditional Null Handling
Use conditional addition to avoid redundant if checks:
// ❌ Not recommended: many if statements
if (StringUtils.isNotBlank(name)) {
wrapper.eq(User::getName, name);
}
if (age != null) {
wrapper.eq(User::getAge, age);
}
// ✅ Recommended: conditional addition
wrapper.eq(StringUtils.isNotBlank(name), User::getName, name)
.eq(Objects.nonNull(age), User::getAge, age);3.3 Explicit Select Fields
Specify required columns to leverage index covering and reduce data transfer:
// ❌ Full‑field query
List<User> users1 = userMapper.selectList(lqw);
// ✅ Select only needed fields
lqw.select(User::getId, User::getName, User::getAge);
List<User> users2 = userMapper.selectList(lqw);4. Practical Development: From “Usable” to “Well‑Used”
4.1 Microservice‑Level Query Encapsulation
When exposing DAO as an RPC service, the native QueryWrapper is heavy. A lightweight QueryCondition object replaces it, containing query fields, order fields, select fields, and pagination parameters.
Example builder usage:
QueryCondition condition = QueryConditionBuilder.builder()
.select(User::getId, User::getName)
.eq(User::getStatus,1)
.like(User::getName,"张")
.in(User::getType,Arrays.asList(1,2,3))
.orderByDesc(User::getCreateTime)
.pageNum(1)
.pageSize(5)
.build();The abstract DAO implementation converts QueryCondition to a LambdaQueryWrapper and delegates to MyBatis‑Plus.
4.2 Three‑Step CRUD Service Generation
Define entity, contract interface extending BaseDao, and implementation extending AbstractBaseDaoImpl. No SQL writing is required.
4.3 Extending BaseMapper with Custom Methods
Create a custom mapper interface (e.g., MyMapper) extending BaseMapper, add methods like int countByEntity(T entity), implement via a custom AbstractMethod and register it with a SqlInjector.
4.4 Built‑in Plugins for System Safety
Two plugins protect production environments:
FullTableScanInterceptor : blocks queries without WHERE clauses.
BlockFullTableOperationInterceptor : blocks updates/deletes without conditions.
5. Conclusion: Why MyBatis‑Plus Is Worth Using
MyBatis‑Plus delivers massive productivity gains with minimal migration cost, type‑safe Lambda APIs, and a plugin architecture that enhances security, pagination, and multi‑tenant support, while standardizing DAO coding practices across teams.
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.
Cognitive Technology Team
Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.
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.
