Using @TableLogic Annotation for Logical Deletion in MyBatis-Plus
This article explains how the @TableLogic annotation in MyBatis-Plus implements logical deletion by converting delete operations into updates, details its parameters, supported field types, global configuration, and provides complete Java and SQL code examples for practical usage.
Introduction
The @TableLogic annotation is used in MyBatis-Plus to achieve logical deletion of database records, affecting insert, select, update, and delete operations by converting physical deletes into update statements that set a designated flag.
Annotation Overview
The annotation has two optional parameters: value (the value representing a non‑deleted record, default empty) and delval (the value representing a deleted record, default empty). When applied to a field, MyBatis‑Plus automatically adds conditions to filter out deleted rows in select and update statements.
Effect on CRUD Operations
Insert : No restriction; the field can be set to the non‑deleted value.
Select : The generated WHERE clause includes the condition that the logical delete column equals the non‑deleted value, thus hiding deleted rows.
Update : An additional condition is appended to prevent updates on rows already marked as deleted.
Delete : The delete statement is transformed into an update that sets the logical delete column to the delval value.
Supported Field Types
All data types are supported, with common choices being Integer , Boolean , or LocalDateTime . When the database column is of type datetime , the non‑deleted and deleted values can be configured as strings (e.g., null ) or functions such as now() .
Global Configuration (application.yml)
# application.yml
mybatis-plus:
global-config:
db-config:
# Global logical delete field name (since 3.3.0)
logic-delete-field: flag
# Value representing a deleted record (default 1)
logic-delete-value: 1
# Value representing a non‑deleted record (default 0)
logic-not-delete-value: 0Code Example – Entity Class
import com.baomidou.mybatisplus.annotation.*;
@TableName(value = "user")
public class AnnotationUser7Bean {
@TableId(value = "user_id", type = IdType.AUTO)
private int userId;
@TableField("name")
private String name;
@TableField("sex")
private String sex;
@TableField("age")
private Integer age;
@TableLogic(value = "0", delval = "1")
private String deleted;
// getters and setters omitted for brevity
@Override
public String toString() {
return "UserBean{" +
"userId=" + userId +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", deleted=" + deleted +
'}';
}
}Code Example – Service/Test
package com.hxstrive.mybatis_plus.simple_mapper.annotation;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hxstrive.mybatis_plus.mapper.AnnotationUser7Mapper;
import com.hxstrive.mybatis_plus.model.AnnotationUser7Bean;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
class AnnotationDemo7 {
@Autowired
private AnnotationUser7Mapper userMapper;
@Test
void contextLoads() throws Exception {
// Delete user with ID 1 if it exists
AnnotationUser7Bean oldUserBean = userMapper.selectById(1);
if (null != oldUserBean) {
userMapper.deleteById(oldUserBean.getUserId());
}
// Query users with ID less than 10
QueryWrapper
wrapper = new QueryWrapper<>();
wrapper.lt("user_id", 10);
for (AnnotationUser7Bean item : userMapper.selectList(wrapper)) {
System.out.println(item);
}
}
}SQL Statements Generated
Preparing: SELECT user_id,name,sex,age,deleted FROM user WHERE user_id=? AND deleted='0'
Parameters: 1(Integer)
Preparing: UPDATE user SET deleted='1' WHERE user_id=? AND deleted='0'
Parameters: 1(Integer)
Preparing: SELECT user_id,name,sex,age,deleted FROM user WHERE deleted='0' AND (user_id < ?)
Parameters: 10(Integer)Conclusion
The @TableLogic annotation provides a convenient way to implement logical deletion in MyBatis‑Plus, allowing developers to keep historical data while preventing accidental physical deletions, and it integrates seamlessly with CRUD operations and global configuration.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.