Master Logical Deletion in Spring Boot 3 with JPA and MyBatis
This article explains the concept and benefits of logical deletion, then demonstrates how to implement it in Spring Boot 3 using JPA annotations like @SQLDelete and @SoftDelete, and MyBatis‑Plus configuration, complete with code examples and SQL output.
Logical deletion is a flexible data handling method widely used to preserve history and prevent accidental loss.
Reasons include easy data recovery, protection of data integrity, meeting audit and compliance requirements, and reducing the risk of accidental operations.
However, logical deletion may cause data bloat and increased query complexity.
2. Practical Examples
2.1 JPA Logical Deletion
Two approaches are presented.
Using @SQLDelete
<code>@Entity
@Table(name = "t_person")
@SQLDelete(sql = "update t_person p set p.deleted = 1 where p.id = ?")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
/**0: normal, 1: deleted*/
@Column(columnDefinition = "int default 0")
private Integer deleted = 0;
// getters, setters
}
</code>Repository interface:
<code>public interface PersonRepository extends JpaRepository<Person, Long> {
}
</code>Unit test:
<code>@Test
public void testDelete() {
this.personRepository.deleteById(2L);
}
</code>The executed SQL updates the deleted column via the @SQLDelete configuration.
Using @SoftDelete
<code>@SoftDelete(
strategy = SoftDeleteType.DELETED,
columnName = "deleted",
converter = DeletedAttributeConverter.class)
public class Person {
// No explicit deleted field needed
}
</code>Converter implementation:
<code>public class DeletedAttributeConverter implements AttributeConverter<Boolean, Integer> {
@Override
public Integer convertToDatabaseColumn(Boolean attribute) {
return attribute == null || !attribute ? 0 : 1;
}
@Override
public Boolean convertToEntityAttribute(Integer dbData) {
return dbData == null || dbData == 0 ? Boolean.FALSE : Boolean.TRUE;
}
}
</code>SQL output shows the update statement generated by @SoftDelete.
2.2 MyBatis Logical Deletion
MyBatis does not provide logical deletion natively; MyBatis‑Plus adds this capability.
Add the dependency:
<code><dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.10.1</version>
</dependency>
</code>Configure global settings:
<code>mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
</code>Entity definition:
<code>@TableName("t_person")
public class Person {
/**0: normal, 1: deleted*/
private Integer deleted = 0;
}
</code>Mapper interface:
<code>public interface PersonMapper extends BaseMapper<Person> {
}
</code>Unit test:
<code>@Test
public void testMyBatisDelete() {
this.personMapper.deleteById(2L);
}
</code>The generated SQL updates the deleted column.
For tables using a different logical‑delete flag, annotate the field with @TableLogic:
<code>public class Person {
@TableLogic
private Integer state;
}
</code>SQL then updates the state column accordingly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
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.