[AI Readability Summary]
MyBatis Plus extends MyBatis and helps you complete CRUD operations, conditional queries, and common data-layer governance with far less boilerplate code. It reduces repetitive work around handwritten Mapper interfaces, XML, and generic SQL. Keywords: MyBatis Plus, Spring Boot, LambdaQueryWrapper.
The technical specification snapshot outlines the stack at a glance
| Parameter | Description |
|---|---|
| Core Language | Java |
| Runtime Framework | Spring Boot |
| ORM Enhancement | MyBatis Plus |
| Typical Protocols | JDBC / SQL |
| Reference Version | mybatis-plus-boot-starter 3.5.3.1 |
| Core Dependencies | BaseMapper, IService, MybatisPlusInterceptor |
| Source Article Profile | Curated from a CSDN technical article |
| Star Count | Not provided in the original content |
MyBatis Plus delivers value by dramatically reducing repetitive data-layer code
MyBatis Plus preserves native MyBatis capabilities and focuses on enhancement rather than replacement. By extending BaseMapper and IService, developers can immediately gain common single-table CRUD capabilities and avoid writing large amounts of template-style SQL and XML.
It works especially well for internal business systems, admin platforms, and standard business-table development. For scenarios such as frequent create, read, update, and delete operations, conditional filtering, pagination, and audit field handling, MP shifts your focus from building plumbing to implementing business rules.
Minimal dependencies and configuration get you running quickly
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
This dependency enables the core MyBatis Plus features in Spring Boot.
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis-plus?useSSL=false
username: root
password: 123456
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # Output SQL logs
This configuration sets up the database connection and enables SQL console logging for easier query debugging.
The combination of entity and Mapper forms the most basic data access unit
The entity class uses annotations to define table mapping. Primary key strategies, field existence, logical deletion, and optimistic locking are all declared at this layer. This approach centralizes rules and reduces scattered XML configuration.
@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO) // Auto-increment primary key strategy
private Long id;
private String name;
private Integer age;
private String email;
}
This code defines the entity object that maps to the user table and declares the primary key generation strategy.
@Repository
public interface UserMapper extends BaseMapper
<User> {
// Inherit BaseMapper to get common CRUD methods automatically
}
This interface allows UserMapper to directly support insert, delete, update, and primary-key lookup operations.
Basic CRUD operations can be called directly through the Mapper
@SpringBootTest
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
void testCrud() {
User user = new User();
user.setName("张三");
user.setAge(30);
user.setEmail("[email protected]");
userMapper.insert(user); // Insert a user record
User dbUser = userMapper.selectById(user.getId()); // Query by primary key
System.out.println(dbUser);
}
}
This test demonstrates the smallest working loop for insert and primary-key lookup without writing XML.
Wrapper is the most productive query abstraction in MyBatis Plus
QueryWrapper and UpdateWrapper let you express conditions without hand-writing WHERE clauses. Compared with string concatenation, they provide a more consistent and reusable approach. Common capabilities include eq, gt, like, between, and orderByDesc.
In most cases, you should prefer LambdaQueryWrapper. Because it references fields through method references, it avoids mistakes in string-based field names and improves refactoring safety.
Lambda condition builders are better for long-term maintenance
@Test
void testLambdaQuery() {
LambdaQueryWrapper
<User> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(User::getAge, 20) // Age greater than 20
.like(User::getName, "张") // Name contains "张"
.orderByDesc(User::getAge); // Sort by age in descending order
List
<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
This code demonstrates a type-safe conditional query style that fits medium and large projects over the long term.
@Test
void testUpdateWrapper() {
UpdateWrapper
<User> wrapper = new UpdateWrapper<>();
wrapper.gt("age", 25) // Update records where age is greater than 25
.set("email", "[email protected]"); // Update the email field in bulk
int rows = userMapper.update(null, wrapper);
System.out.println("更新行数=" + rows);
}
This code shows how to build an update statement directly with conditions when no entity object is passed.
The Service layer abstraction further unifies the business access entry point
When a project grows into a multi-module collaboration environment, relying only on Mapper is often not enough. MyBatis Plus provides generic service-layer implementations through IService and ServiceImpl, giving business code a more consistent entry point.
public interface UserService extends IService
<User> {
// Extend domain methods here if needed
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService {
}
This code establishes a standard Service structure that is suitable for reusing common methods between controllers and business services.
Controllers can directly reuse the generic capabilities of IService
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public List
<User> list() {
return userService.list(); // Query all users directly
}
}
This controller code shows that the Service layer can directly expose standard CRUD capabilities.
Pagination, logical deletion, and auto-fill are the most commonly used engineering features
Pagination is essential for admin-side list queries. MyBatis Plus wires in PaginationInnerInterceptor through MybatisPlusInterceptor, allowing plugins to intercept the SQL execution chain and eliminate handwritten pagination SQL.
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // Enable pagination plugin
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // Enable optimistic locking plugin
return interceptor;
}
}
This configuration enables pagination and optimistic locking in one place, which is a common infrastructure pattern in real projects.
@Test
void testPage() {
Page
<User> page = new Page<>(1, 5); // Page 1, 5 records per page
userMapper.selectPage(page, null);
System.out.println(page.getRecords());
}
This code demonstrates the standard way to execute a paginated query.
Logical deletion and audit fields significantly reduce common business checks
Logical deletion uses a marker field instead of physically deleting records, which makes recovery, auditing, and history tracking easier. Auto-fill handles fields such as createTime and updateTime consistently, so you do not have to manage them manually in every endpoint.
public class User {
@TableLogic
private Integer deleted; // 0 = not deleted, 1 = deleted
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@Version
private Integer version; // Optimistic lock version number
}
This entity definition centralizes logical deletion, audit fields, and optimistic locking.
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); // Fill create time on insert
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date()); // Fill update time on insert
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); // Refresh update time on update
}
}
This handler automatically maintains audit fields during insert and update operations.
The code generator is ideal for improving efficiency at scale in standardized projects
For systems with stable table structures and many modules, the code generator can batch-generate Entity, Mapper, Service, and Controller classes. It is not a core runtime capability, but it is highly efficient during project bootstrapping.
FastAutoGenerator.create("jdbc:mysql://localhost:3306/your_db", "username", "password")
.globalConfig(builder -> builder.outputDir("D://code")) // Specify the output directory
.packageConfig(builder -> builder.parent("com.example")) // Specify the base package
.strategyConfig(builder -> builder.addInclude("user", "order")) // Specify the tables to generate
.execute();
This code quickly generates a standard layered code skeleton from the database schema.
The conclusion is that MyBatis Plus fits most standard CRUD systems
If your project mainly involves single-table operations, paginated lists, back-office management, audit fields, and a generic service layer, MyBatis Plus is one of the most cost-effective choices for Java back-end development. Its greatest strength is not that it writes all SQL for you, but that it minimizes repetitive work.
For complex joins, extreme performance tuning, or highly specialized SQL scenarios, you can still fall back to native MyBatis. That is exactly why MP works best as the default option, not the only option.
The FAQ clarifies common implementation questions
1. Can MyBatis Plus completely replace MyBatis?
No. It is an enhancement layer that works well for standard CRUD and general-purpose scenarios. For complex joins and manually optimized SQL, you should still combine it with native MyBatis.
2. Why is LambdaQueryWrapper the preferred option?
Because it binds fields through method references instead of hard-coded string field names, making it safer for refactoring, field changes, and compile-time validation.
3. Should logical deletion, auto-fill, and optimistic locking be used together?
Yes, in most internal business systems. These three features address data retention, audit consistency, and concurrency safety respectively. Together, they provide a more production-ready data governance model.
Core summary
This article systematically reconstructs the core capabilities and best practices of MyBatis Plus, including rapid integration, BaseMapper and IService, Wrapper-based condition builders, the pagination plugin, logical deletion, auto-fill, optimistic locking, and the code generator. It helps Java back-end developers build a high-quality data access layer with less code.