Master MyBatis-Plus: From Basics to Advanced Features

This article introduces MyBatis-Plus, an enhancement layer for MyBatis, and walks through its core features—non‑intrusive CRUD, Lambda queries, primary‑key strategies, automatic field filling, optimistic locking, pagination, logical delete, performance analysis, condition builders, and a code generator—providing complete code examples and configuration steps for Spring Boot integration.

IT Niuke
IT Niuke
IT Niuke
Master MyBatis-Plus: From Basics to Advanced Features

MyBatis‑Plus Overview

Non‑intrusive: adds features without changing existing MyBatis code.

Low overhead: basic CRUD is auto‑injected with negligible performance impact.

Powerful CRUD: built‑in BaseMapper and service, rich QueryWrapper, Lambda support.

Automatic primary‑key generation: four strategies (ID_WORKER/Snowflake, AUTO, INPUT, UUID, ID_WORKER_STR).

ActiveRecord mode, global method injection, code generator, pagination plugin (supports MySQL, MariaDB, Oracle, DB2, H2, HSQL, SQLite, PostgreSQL, SQLServer), performance analysis plugin, logical delete interceptor.

Quick Start

Create database and table:

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

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]');

Add Maven/Gradle dependency mybatis-plus-boot-starter to a Spring Boot project.

Configure datasource (application.yml or 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

Define entity class User with fields id, name, age, email (optionally Lombok getters/setters).

Create mapper interface extending BaseMapper<User> and annotate with @Repository (or use @Mapper and enable @MapperScan).

CRUD Extensions

Insert with Automatic ID

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

Primary‑key strategies are defined in IdType enum:

public enum IdType {
    AUTO(0),      // DB auto‑increment
    NONE(1),      // No primary key set
    INPUT(2),     // Manually input
    ID_WORKER(3), // Default Snowflake
    UUID(4),      // UUID string
    ID_WORKER_STR(5);
}

Automatic Field Filling

Mark timestamp fields with @TableField(fill = FieldFill.INSERT) or FieldFill.INSERT_UPDATE and implement MetaObjectHandler:

@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 the field with @Version, and register the interceptor:

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

Test case – successful update:

@Test
public void versionTest() {
    User user = userMapper.selectById(1L);
    user.setName("派大星");
    user.setEmail("[email protected]");
    userMapper.updateById(user); // succeeds
}

Test case – failure when another thread updates first:

@Test
public void optimisticLockerTest() {
    User user1 = userMapper.selectById(1L);
    User user2 = userMapper.selectById(1L);
    user1.setName("派大星111");
    userMapper.updateById(user2); // increments version
    userMapper.updateById(user1); // throws OptimisticLockException / returns 0
}

Query Operations

@Test
public void testSelect() {
    User user = userMapper.selectById(1L);
    System.out.println(user);
}

List<User> batch = userMapper.selectBatchIds(Arrays.asList(1,2,3));
Map<String,Object> map = new HashMap<>();
map.put("name","派大星");
map.put("age",16);
List<User> byMap = userMapper.selectByMap(map);

Pagination

Register pagination interceptor and perform a paged query:

@Bean
public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
}

Page<User> page = new Page<>(1, 5); // page 1, size 5
IPage<User> result = userMapper.selectPage(page, null);
result.getRecords().forEach(System.out::println);

Logical Delete

Mark a field with @TableLogic, configure logical‑delete values, and provide LogicSqlInjector bean:

@TableLogic
private Integer deleted;

@Bean
public ISqlInjector sqlInjector() {
    return new LogicSqlInjector();
}

# application.properties
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

Calling deleteById sets deleted=1 instead of removing the row.

Performance Analysis Plugin

Register PerformanceInterceptor with a maximum execution time (e.g., 100 ms) and enable it in dev or test profile:

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

Condition Builder

Common QueryWrapper usage examples:

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")
       .isNotNull("email")
       .ge("age", 12)
       .eq("name", "派大星")
       .between("age", 16, 30)
       .notLike("name", "l")
       .likeRight("email", "t")
       .inSql("id", "select id from user where id<3")
       .orderByDesc("id");
List<User> list = userMapper.selectList(wrapper);

Code Generator

Configure AutoGenerator to generate entity, mapper, service, and controller code:

public class Generator {
    public static void main(String[] args) {
        AutoGenerator mpg = new AutoGenerator();
        // Global config
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("java资讯");
        gc.setOpen(false);
        gc.setFileOverride(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.setTablePrefix("i_");
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setControllerMappingHyphenStyle(true);
        mpg.setStrategy(strategy);
        // Execute generation
        mpg.execute();
    }
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javacode generationSpring BootORMpaginationoptimistic lockMyBatis-PlusCRUD
IT Niuke
Written by

IT Niuke

Focused on IT technology sharing, original and innovative content. IT Niuke, we grow together.

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.