Comprehensive Guide to MyBatis-Plus: Quick Start, Core Features, and Advanced Usage

This article provides a detailed tutorial on using MyBatis-Plus with Spring Boot, covering installation, quick start, CRUD operations, annotation usage, condition builders, pagination, AR mode, primary key strategies, configuration options, code generation, logical deletion, auto-filling, optimistic locking, performance analysis, multi‑tenant support, dynamic table names, and best‑practice summaries.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Comprehensive Guide to MyBatis-Plus: Quick Start, Core Features, and Advanced Usage

MyBatis-Plus is an enhancement tool for MyBatis that simplifies development and improves efficiency. This guide demonstrates how to integrate MyBatis-Plus 3.4.2 with Spring Boot, starting from project setup and dependency configuration.

Quick Start

Create a Spring Boot project and add the following dependencies in <pom.xml>:

<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/><!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatis-plus</name>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Configure the database in application.yml:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/yogurt?serverTimezone=Asia/Shanghai
    username: root
    password: root
mybatis-plus:
  global-config:
    db-config:
      id-type: auto

Create an entity class User with Lombok annotations and fields that map to the user table, using @TableField for custom column mapping when needed.

package com.example.mp.po;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
    private Long managerId;
    private LocalDateTime createTime;
}

Create a mapper interface extending BaseMapper<User>:

package com.example.mp.mappers;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mp.po.User;
public interface UserMapper extends BaseMapper<User> {}

Enable mapper scanning in the Spring Boot application:

@SpringBootApplication
@MapperScan("com.example.mp.mappers")
public class MybatisPlusApplication {
    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);
    }
}

Core Features

MyBatis-Plus provides eight built‑in annotations such as @TableName, @TableId, @TableField, @Version, @TableLogic, etc., to control table‑entity mapping, primary key strategy, logical deletion, optimistic locking, and more.

CRUD Operations

All basic CRUD methods are available through BaseMapper, e.g., insert, deleteById, updateById, selectById, selectList, and batch variants. Example of inserting a record:

@Test
public void testInsert() {
    User user = new User();
    user.setId(2L);
    user.setAge(18);
    userMapper.insert(user);
}

Complex queries can be built with QueryWrapper or LambdaQueryWrapper. For instance, to find users whose name contains "黄" and age is less than 25:

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name", "黄").lt("age", 25);
List<User> users = userMapper.selectList(wrapper);

Lambda version (type‑safe):

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(User::getName, "黄").lt(User::getAge, 25);

Condition Builder Tips

Use and(q -> ...) or or(q -> ...) with lambda to group conditions.

Use

apply("date_format(create_time, '%Y-%m-%d') = {0}", "2021-03-22")

for custom SQL fragments.

Pass a boolean flag to any condition method to include it only when the flag is true.

Pagination

Register a pagination interceptor:

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

Then query with a Page object:

Page<User> page = new Page<>(3, 2);
Page<User> result = userMapper.selectPage(page, wrapper);
System.out.println("Total=" + result.getTotal());
result.getRecords().forEach(System.out::println);

Active Record (AR) Mode

Make the entity extend Model<User> and use methods like insert(), updateById(), selectById(), and deleteById() directly on the object.

User user = new User();
user.setId(15L);
user.setName("我是AR猪");
user.insert();

Primary Key Strategies

Configure global or per‑entity primary‑key generation via @TableId(type = IdType.AUTO), IdType.ASSIGN_ID, IdType.INPUT, etc., or set the global strategy in application.yml under mybatis-plus.global-config.db-config.id-type.

Logical Deletion

Enable logical delete by configuring logic-delete-field, logic-delete-value, and logic-not-delete-value in application.yml. The framework will automatically convert DELETE statements to UPDATE that sets the delete flag, and add the flag condition to all SELECT, UPDATE, and DELETE operations.

Auto‑Filling

Mark fields with @TableField(fill = FieldFill.INSERT) or FieldFill.UPDATE and implement a MetaObjectHandler bean to set timestamps or other values automatically.

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        strictFillStrategy(metaObject, "createTime", LocalDateTime::now);
    }
    @Override
    public void updateFill(MetaObject metaObject) {
        strictFillStrategy(metaObject, "updateTime", LocalDateTime::now);
    }
}

Optimistic Locking

Add the optimistic‑locker interceptor and annotate a version field with @Version. The framework will add WHERE version = ? to updates and increment the version automatically.

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

Performance Analysis

Integrate the P6Spy library, configure spy.properties, and replace the JDBC driver with com.p6spy.engine.spy.P6SpyDriver to log SQL execution times.

Multi‑Tenant Support

Register a TenantLineInnerInterceptor with a custom TenantLineHandler that returns the tenant ID and the tenant column name, and optionally skips tables that should not be filtered.

Dynamic Table Names

Use DynamicTableNameInnerInterceptor and provide a map of table‑name handlers to replace logical table names at runtime, useful for sharding scenarios.

Overall, MyBatis‑Plus offers a rich set of utilities that dramatically reduce boilerplate code for CRUD operations, while still allowing fine‑grained control through custom SQL, interceptors, and advanced features such as logical deletion, auto‑filling, optimistic locking, multi‑tenant filtering, and dynamic table routing.

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.

JavaSpring BootORMmybatis-plusCRUD
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

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.