Comprehensive MyBatis‑Plus CRUD Guide for Spring Boot Applications

This article provides a comprehensive step‑by‑step guide on using MyBatis‑Plus in a Spring Boot application, covering table creation, Maven dependencies, configuration, entity and mapper definitions, CRUD testing, auto‑fill, optimistic and logical deletion, pagination, performance monitoring, query wrappers, and code generation.

Top Architect
Top Architect
Top Architect
Comprehensive MyBatis‑Plus CRUD Guide for Spring Boot Applications

First, create the user table with the following SQL script:

DROP TABLE IF EXISTS user;
CREATE TABLE user (
  id BIGINT(20) NOT NULL COMMENT '主键ID',
  name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
  age INT(11) NULL DEFAULT NULL COMMENT '年龄',
  email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
  PRIMARY KEY (id)
);
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]');

Import the required Maven dependencies for the MySQL driver, Lombok, and MyBatis‑Plus:

<!-- 数据库驱动 -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- lombok -->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.0.5</version>
</dependency>

Configure the datasource in application.yml:

spring:
  profiles:
    active: dev
  datasource:
    # MySQL driver (choose version 5 or 8)
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: root

Define the entity class User with Lombok annotations:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
  private Long id;
  private String name;
  private Integer age;
  private String email;
}

Create the mapper interface extending BaseMapper:

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kuang.pojo.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper extends BaseMapper<User> {
  // CRUD methods are provided by BaseMapper
}

Write test cases using @SpringBootTest to demonstrate CRUD operations, auto‑fill, optimistic lock, logical delete, pagination and query wrappers. Example of an insert test:

@Test
public void testInsert() {
  User user = new User();
  user.setName("kwhua_mybatis-plus_insertTest");
  user.setAge(15);
  user.setEmail("[email protected]");
  int result = userMapper.insert(user);
  System.out.println(result);
  System.out.println(user);
}

Configure MyBatis‑Plus plugins such as optimistic locking, performance monitoring and pagination in a Spring configuration class:

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

@Configuration
public class MyBatisPlusConfig {
  @Bean
  public OptimisticLockerInterceptor optimisticLockerInterceptor() {
    return new OptimisticLockerInterceptor();
  }
  @Bean
  public PerformanceInterceptor performanceInterceptor() {
    PerformanceInterceptor pi = new PerformanceInterceptor();
    pi.setMaxTime(100);
    pi.setFormat(true);
    return pi;
  }
  @Bean
  public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
  }
}

Use QueryWrapper for conditional queries, for example to fetch users whose name and email are not null and age ≥ 18:

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")
       .isNotNull("email")
       .ge("age", 18);
userMapper.selectList(wrapper).forEach(System.out::println);

Demonstrate optimistic locking by adding a @Version field to the entity and registering the OptimisticLockerInterceptor. The version column is automatically incremented on successful updates and prevents lost updates in concurrent scenarios.

Implement logical deletion by adding a @TableLogic annotated deleted field, configuring LogicSqlInjector, and setting the global configuration values for logical delete in application.yml. Deleting a record sets deleted = 1 instead of physically removing the row.

Enable pagination with PaginationInterceptor and use the Page object:

Page<User> page = new Page<>(2, 5);
userMapper.selectPage(page, null);
page.getRecords().forEach(System.out::println);
System.out.println(page.getTotal());

Finally, generate boilerplate code automatically with MyBatis‑Plus AutoGenerator. The generator is configured with global settings, data source, package info, and strategy (naming, Lombok, logical delete, auto‑fill, version field, table prefix, REST style, etc.). Running the generator creates entity, mapper, service, controller and XML files for the specified tables.

public class GenerateCode {
  public static void main(String[] args) {
    AutoGenerator mpg = new AutoGenerator();
    // Global config, data source, package config, strategy config omitted for brevity
    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.

JavaORMSpringBootmybatis-plusCRUD
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

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.