Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

MyBatis-Plus Essential Features Guide

Tech May 12 3

MyBatis-Plus is an enhanced toolkit built on top of MyBatis, providing powerful CRUD operations without modifying the original framework. It offers zero intrusion, minimal performance overhead, built-in CRUD functionality, Lambda expression support, code generation, pagination plugins, and multi-database compatibility.

Official Website: https://www.baomidou.comDocumentation: https://www.baomidou.com/introduce/

The MyBatisPlus team provides an official starter that bundles both MyBatis and MyBatisPlus features with auto-configuration capabilities. You can simply replace the MyBatis starter with the MyBatisPlus starter.

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

  1. Quick Start

1.1 BaseMapper

Let's use a User table for demonstrating CRUD operations.

Create a custom Mapper interface that extends MyBatisPlus's BaseMapper interface with the entity class as the generic type. This interface provides pre-configured CRUD methods that can be used directly and won't conflict with any custom MyBatis methods you write.

public interface UserMapper extends BaseMapper<User> {
   
   
}

1.2 Key Annotations

MP scans entity classes and uses reflection to extract class information as database table metadata. The default mapping rules are:

  • Convert class name from camelCase to snake_case for table names
  • Fields named id are treated as primary keys
  • Variable names are converted from camelCase to snake_case for column names

You can override these defaults using the following annotations:

  • @TableName: Specifies the exact table name
  • @TableId: Marks and configures the primary key field with value for column name and type for ID generation strategy Available IdType options:
    1. AUTO: Auto-increment in the database
    2. INPUT: Manually set via setter methods
    3. ASSIGN_ID: Assigned ID using the IdentifierGenerator interface's nextId method, with DefaultIdentifierGenerator (Snowflake algorithm) as the default implemantation
  • @TableField: Marks regular table columns Use this annotation in these scenarios:
    • When field names don't match database column names
    • When field names start with "is" for Boolean types (MP strips "is" by default, so underscore must be added manually)
    • When field names conflict with SQL reserved words (wrap with backticks)
    • When a field isn't a database column (set exist = false)

1.3 Common Configuration

MP configuration extends MyBatis native settings with its own specific options. Refer to official documentation for complete details.

mybatis-plus:
  type-aliases-package: com.example.app.domain.entity
  mapper-locations: "classpath*:/mapper/**/*.xml"
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
  global-config:
    db-config:
      id-type: assign_id
      update-strategy: not_null

1.4 Core Concepts

  • POJO (Plain Ordinary Java Object): Simple Java objects that serve as intermediate layers. A POJO becomes a PO after persistence, a DTO during data transfer, and a VO when mapped to presentation layers.
  • VO (View Object): Display-oriented objects that encapsulate all data for a specific page or component. When a DTO maps to a single VO, they're equivalent. When a DTO maps to multiple VOs, the presentation layer must convert VO data to DTO format before calling service layer methods, ensuring proper decoupling between layers.
  • BO (Business Object): Objects that encapsulate business logic, potentially containing multiple other objects. For instance, a resume might contain education history, work experience, and social connections—each mapped to separate POs while a Resume BO coordinates them for business operations.
  • DTO (Data Transfer Object): Used for remote calls and scenarios requiring bulk data transfer. If a database table has 100 fields but the UI only needs 10, transmitting a full PO would expose unnecessary structure. A DTO containing only those 10 fields solves this efficiently. When used for UI display, a DTO functions as a VO.
  • DO (Domain Object): Business domain abstractions representing tangible or intangible entities. These serve as an abstraction layer between database and business logic, typically used in Service layers when accessing SQL. Commonly named xxxDO where xxx corresponds to the table name. DOs are a type of Entity with database mappings.
  • PO (Persistent Object): Objects that directly map to persistence layer structures (typically relational databases). Each database record corresponds to a PO instance, enabling object-oriented manipulation of data records with easy conversion to other object types.
  1. Core Features

2.1 Query Wrappers

MyBatis-Plus provides various Wrapper classes for constructing complex WHERE conditions that cover virtually all query requirements in typical development.

2.1.1 QueryWrapper

QueryWrapper and LambdaQueryWrapper are primarily used for building WHERE clauses in SELECT, DELETE, and UPDATE statements.

【Example】Query Using QueryWrapper

SQL Statements

# Example 1: Find users with 'o' in their name, balance >= 1000, return id, username, info, balance
select id, username, info, balance
from user
where username like 'o' and balance >= 1000

# Example 2: Update balance to 2000 for user named 'jack'
update user
	set balance = 2000
	where (username = 'jack')

MP Implementation

/* Example 1: Query users matching criteria */
@Test
void testQueryWrapper1() {
   
   
	QueryWrapper<User> queryConditions = new QueryWrapper<>()
			.select("id", "username", "info", "balance")
			.like("username", "o")
			.ge("balance", 1000);
	List<User> result = userMapper.selectList(queryConditions);
	result.forEach(System.out::println);
}

/* Example 2: Update specific user's balance */
@Test
void testQueryWrapper2() {
   
   
	User targetUser = new User();
	targetUser.setBalance(2000);
	QueryWrapper<User> condition = new QueryWrapper<>().eq("username", "jack");
	userMapper.update(targetUser, condition);
}

2.1.2 UpdateWrapper

UpdateWrapper and LambdaUpdateWrapper are useful when SET clause logic is complex or involves computed values.

【Example】Update Using UpdateWrapper

SQL Statement

# Example: Deduct 200 from balances of users with id 1, 2, or 4
update user
	set balance = balance - 200
	where id in (1, 2, 4)

MP Implementation

/* Example: Batch balance deduction */
@Test
void testUpdateWrapper() {
   
   
	List<Long> targetIds = List.of(1L, 2L, 4L);
	UpdateWrapper<User> modifier = new UpdateWrapper<>()
			.setSql("balance = balance - 200")
			.in("id", targetIds);
	userMapper.update(null, modifier);
}

2.1.3 Lambda Query Wrappers

LambdaQueryWrapper and LambdaUpdateWrapper eliminate hardcoded column names by referencing entity class methods instead.

【Example】Refactoring Example 2.1.1 with Lambda Wrapper

/* Refactored testQueryWrapper1 */
LambdaQueryWrapper<User> conditions = new LambdaQueryWrapper<>()
		.select(User::getId, User::getUsername, User::getInfo, User::getBalance)
		.like(User::getUsername, "o")
		.ge(User::getBalance, 1000);

2.2 Custom SQL Statements

You can leverage MP's Wrapper classes to build complex WHERE conditions while writing the remaining SQL yourself.

【Example】Deduct specified amount from balances of users within given ID list (e.g., IDs 1, 2, 4)

Steps for MP Custom SQL:

  1. Build WHERE conditions using Wrapper
/* Service Layer */
/* customSqlSegment example */
List<Long> userIds = List.of(1L, 2L, 4L);
int deductionAmount = 200;
LambdaQueryWrapper<User> filter = new LambdaQueryWrapper<>().in(User::getId, userIds);
userMapper.deductBalance(filter, deductionAmount);

  1. Declare wrapper parameter with @Param annotation in mapper method (must be "ew" or use Constants.WRAPPER)
/* UserMapper.java */
void deductBalance(@Param("ew") LambdaQueryWrapper<User> filter, @Param("amount") int deductionAmount);

  1. Write custom SQL using Wrapper conditions
<update id="deductBalance">
	update tb_user set balance = balance - #{amount} ${ew.customSqlSegment}
</update>

2.3 IService Interface

MP provides the Service layer with an IService interface and ServiceImpl implementation class.

2.3.1 Basic Usage

Your custom service interface should extend IService with your entity type, and your implementation class should extend ServiceImpl while implementing your custom interface.

/* UserService.java */
public interface UserService extends IService<User> {
   
   
}

/* UserServiceImpl.java */
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
   
   
}

2.3.2 CRUD Implementation Example

【Example】Implementing RESTful API endpoints

Add swagger (API documentation annotations) and web dependencies

<!-- swagger -->
<dependency>
	<groupId>com.github.xiaoymins</groupId>
	<artifactId>knife4j-openapi2-spring-boot-starters</artifactId>
	<version>4.1.0</version>
</dependency>
<!-- web -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

Configure swagger settings

# application.yaml
knife4j:
  enable: true
  openapi:
    title: User Management API Documentation
    description: "User Management API Documentation"
    version: v1.0.0
    group:
      default:
        group-name

Tags: MyBatis-Plus

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.