Backend Development 19 min read

Comprehensive MyBatis‑Plus Guide: Overview, Quick Start, CRUD Extensions, Optimistic Lock, Logical Delete, Pagination, and Code Generator

This article provides a detailed introduction to MyBatis‑Plus, covering its core features, step‑by‑step quick‑start instructions, CRUD operations, advanced configurations such as optimistic locking, logical deletion, pagination, performance analysis, and the built‑in code generator, all illustrated with complete Java code examples.

Top Architect
Top Architect
Top Architect
Comprehensive MyBatis‑Plus Guide: Overview, Quick Start, CRUD Extensions, Optimistic Lock, Logical Delete, Pagination, and Code Generator

MyBatis‑Plus Overview

MyBatis‑Plus (MP) is an enhancement tool for MyBatis that adds powerful features without altering the original framework, aiming to simplify development and improve efficiency.

Key Features

Non‑intrusive: Enhances MyBatis without affecting existing projects.

Low Overhead: Auto‑injects basic CRUD with negligible performance impact.

Powerful CRUD: Built‑in generic Mapper and Service enable most single‑table operations with minimal configuration.

Lambda Support: Allows type‑safe query construction using lambda expressions.

Primary Key Generation: Supports four strategies, including a distributed ID generator.

ActiveRecord Mode: Entities can inherit Model for direct CRUD operations.

Global Operations: One‑time method injection for reusable logic.

Code Generator: Generates Mapper, Model, Service, and Controller code via Maven plugin or programmatic API.

Pagination Plugin: Physical pagination with support for many databases.

Performance Analyzer: Outputs SQL statements and execution time.

Global Interceptor: Smart delete/update analysis to prevent accidental data loss.

Quick Start

1. Create a database and table:

DROP TABLE IF EXISTS user;
CREATE TABLE user (
id BIGINT(20) NOT NULL COMMENT 'Primary Key ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT 'Name',
age INT(11) NULL DEFAULT NULL COMMENT 'Age',
email VARCHAR(50) NULL DEFAULT NULL COMMENT 'Email',
PRIMARY KEY (id)
);

2. Insert sample data:

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');

3. Add the starter dependency to a Spring Boot project:

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>Latest Version</version>
</dependency>

4. Configure the datasource in application.yml (or application.properties ).

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&useSSL=true&useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=233031

5. Define the entity class:

public class User {
private Long id;
private String name;
private Integer age;
private String email;
// constructors, getters, setters
}

6. Create a mapper that extends BaseMapper<User> :

@Repository
public interface UserMapper extends BaseMapper
{
// CRUD methods are provided automatically
}

Logging Configuration

Enable SQL logging for testing:

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

CRUD Extensions

Insert

@Test
public void testInsert() {
User user = new User();
user.setName("派大星学Java");
user.setAge(16);
user.setEmail("[email protected]");
int rows = userMapper.insert(user); // ID is auto‑filled
System.out.println(rows);
System.out.println(user);
}

The default primary‑key strategy is a globally unique ID generated by the Snowflake algorithm.

Update

@Test
public void updateTest() {
User user = new User();
user.setId(5L);
user.setName("我想创建公众号");
user.setAge(16);
int rows = userMapper.updateById(user);
System.out.println(rows);
}

Automatic Field Filling

Configure @TableField(fill = FieldFill.INSERT) for createTime and @TableField(fill = FieldFill.INSERT_UPDATE for updateTime , then implement a MetaObjectHandler to set the values.

@Slf4j
@Component
public class MyDateObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}

Optimistic Lock

Add a version column, annotate it with @Version , and register the OptimisticLockerInterceptor bean.

@MapperScan("com.pdx.mapper")
@EnableTransactionManagement
@Configuration
public class MyBatisPlusConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}

Logical Delete

Use @TableLogic on a deleted field and configure the global values.

@TableLogic
private Integer deleted;
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

Pagination

@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
@Test
public void pageTest() {
Page
page = new Page<>(1, 5);
IPage
result = userMapper.selectPage(page, null);
result.getRecords().forEach(System.out::println);
}

Code Generator

Use AutoGenerator to generate entity, mapper, service, and controller code automatically.

public class Generator {
public static void main(String[] args) {
AutoGenerator mpg = new AutoGenerator();
// Global config
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
gc.setAuthor("派大星");
gc.setOpen(false);
gc.setServiceName("%sService");
gc.setIdType(IdType.ID_WORKER_STR);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
// Data source
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/kuangstudy?useUnicode=true&characterEncoding=utf-8&useSSL=false");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("233031");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// Package config
PackageConfig pc = new PackageConfig();
pc.setModuleName("pdx");
pc.setParent("com");
pc.setController("controller");
pc.setEntity("pojo");
pc.setService("service");
pc.setMapper("mapper");
mpg.setPackageInfo(pc);
// Strategy config
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("pdx_download");
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
// Execute
mpg.execute();
}
}

Performance Analysis Plugin

@Bean
@Profile({"dev", "test"})
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor pi = new PerformanceInterceptor();
pi.setMaxTime(100); // ms
pi.setFormat(true);
return pi;
}

Use the interceptor to log slow SQL statements during development.

The article concludes with a reminder that mastering all CRUD operations and extensions of MyBatis‑Plus is essential for backend development.

javadatabaseORMSpringBootMyBatis-PlusCRUDCodeGeneration
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login 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.