Master MyBatis‑Plus in Spring Boot: From Quick Start to Advanced Features

This guide walks through integrating MyBatis‑Plus with Spring Boot, covering dependency setup, configuration, entity annotations, CRUD operations, pagination, logical deletion, enum handling, automatic field filling, multi‑data‑source support, and testing with concrete code examples and detailed explanations.

Architect
Architect
Architect
Master MyBatis‑Plus in Spring Boot: From Quick Start to Advanced Features

Quick Start

The article assumes a Spring Boot, Maven, JDK 1.8, and MySQL environment. It creates a database using the utf8mb4 charset to store emoji characters.

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

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.27</version>
</dependency>

<!-- mybatis‑plus multi‑data‑source -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.5.0</version>
</dependency>

Spring Boot’s main class is annotated with @MapperScan("com.wjbgn.user.mapper") to locate mapper interfaces.

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@MapperScan("com.wjbgn.user.mapper")
@SpringBootApplication
public class RobNecessitiesUserApplication {
    public static void main(String[] args) {
        SpringApplication.run(RobNecessitiesUserApplication.class, args);
    }
}

Data‑source configuration uses HikariCP (recommended over druid for performance) and defines a primary master and a slave (both pointing to the same DB in the example).

spring:
  datasource:
    dynamic:
      primary: master
      strict: false
      datasource:
        master:
          url: jdbc:mysql://127.0.0.1:3306/rob_necessities?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
        slave_1:
          url: jdbc:mysql://127.0.0.1:3306/rob_necessities?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
          username: root
          password: 123456

# HikariCP tuning
spring:
  datasource:
    dynamic:
      hikari:
        max-lifetime: 1800000
        connection-timeout: 5000
        idle-timeout: 3600000
        max-pool-size: 12
        min-idle: 4
        connection-test-query: /**ping*/

Service Startup

Running the Spring Boot application prints a successful start‑up log, confirming that MyBatis‑Plus is correctly wired.

Usage

Entity Annotations

MyBatis‑Plus provides a set of annotations to simplify mapping. Example entity:

@TableName("user")
public class UserDO {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @TableField("nickname")
    private String nickname;

    private String realName;
}

Key annotations explained: @TableName: specifies the table name. @TableId: defines primary‑key strategy. IdType options include AUTO (DB auto‑increment), NONE, INPUT, ASSIGN_ID (snowflake), and ASSIGN_UUID. @TableField: maps a field to a column and can set conditions such as SqlCondition.EQUAL, LIKE, etc.

CRUD

Service layer extends IService<UserDO> and implementation extends ServiceImpl<UserMapper, UserDO>:

public interface IUserService extends IService<UserDO> {}

public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements IUserService {}

Mapper layer simply extends BaseMapper<UserDO>:

@Mapper
public interface UserMapper extends BaseMapper<UserDO> {}

Pagination

Configure the pagination interceptor:

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.wjbgn.*.mapper*")
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

Logical Deletion

Global logical‑delete configuration (since 3.3.0) can be set in application.yml:

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: isDelete
      logic-delete-value: 1
      logic-not-delete-value: 0

Or use the @TableLogic annotation on the entity field:

@TableLogic
private Integer isDelete;

Enum Handling

Define an enum implementing IEnum<Integer> and annotate with @JsonFormat(shape = JsonFormat.Shape.OBJECT) to serialize both code and name:

public enum SexEnum implements IEnum<Integer> {
    MAN(1, "男"),
    WOMAN(2, "女");
    private Integer code;
    private String name;
    SexEnum(Integer code, String name) { this.code = code; this.name = name; }
    @Override
    public Integer getValue() { return code; }
    public String getName() { return name; }
}

Entity field uses the enum directly:

@TableField(value = "sex")
private SexEnum sex;

Configure package scanning for enums:

mybatis-plus:
  typeEnumsPackage: com.wjbgn.*.enums

Automatic Field Filling

Implement MetaObjectHandler to auto‑populate timestamps:

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

Entity fields:

@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;

@TableField(value = "update_time", fill = FieldFill.UPDATE)
private LocalDateTime updateTime;

Multi‑DataSource

MyBatis‑Plus supports various multi‑data‑source strategies. Example YAML for master‑slave, multiple masters, or mixed DB types is provided, and the @DS annotation can be placed on classes or methods (method‑level takes precedence).

@DS("slave_1")
public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements IUserService {
    @DS("slave_1")
    public List<UserDO> getList() { return this.list(); }

    @DS("master")
    public int saveUser(UserDO user) {
        return this.save(user) ? 1 : 0;
    }
}

Testing

A sample user table is created with fields id, nickname, sex, create_time, and is_delete (logical delete flag).

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(255) NOT NULL COMMENT '昵称',
  `sex` tinyint(1) NOT NULL COMMENT '性别,1男2女',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 1是,0否',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8mb4;

Controller exposes CRUD endpoints for demonstration:

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private IUserService userService;

    @RequestMapping("/save")
    public boolean save() {
        UserDO user = new UserDO();
        user.setNickname("大漂亮");
        user.setSex(SexEnum.MAN);
        return userService.save(user);
    }

    @RequestMapping("/update")
    public boolean update(@RequestParam String nickname, @RequestParam Long id) {
        UserDO user = new UserDO();
        user.setId(id);
        user.setNickname(nickname);
        return userService.updateById(user);
    }

    @RequestMapping("/delete")
    public boolean delete(@RequestParam Long id) {
        return userService.removeById(id);
    }

    @RequestMapping("/list")
    public List<UserDO> list() {
        return userService.list();
    }

    @RequestMapping("/page")
    public Page page(@RequestParam int current, @RequestParam int size) {
        return userService.page(new Page<>(current, size), new QueryWrapper<>(new UserDO()));
    }
}

Running these endpoints confirms that MyBatis‑Plus integration works as expected, covering the most common features such as annotations, CRUD, pagination, logical deletion, enum conversion, automatic filling, and multi‑data‑source routing.

Spring BootPaginationMyBatis-PlusCRUDLogical DeletionMulti-DataSourceEnum Mapping
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

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.