MyBatis 中,如何实现逻辑删除?

时间:2025-04-01 13:05:32

MyBatis 中,如何实现逻辑删除?
在 MyBatis 中,可以通过两种方式实现逻辑删除:

  1. 使用 UPDATE 语句,将删除标志位置为已删除

在数据库表中增加一个标志列,通常取名为 delete_flag,表示该行记录是否被删除。在执行删除操作时,不是真正地删除记录,而是将 delete_flag 的值设置为已删除状态。通过在查询语句中加入 delete_flag 的判断,就可以实现逻辑删除的效果。

例如,在一个用户表中添加 delete_flag 字段表示删除标志:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `delete_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标志',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

在 mapper 的配置文件中,可以定义一个 UPDATE 语句来将指定的用户记录的 delete_flag 字段更新为已删除状态:

<update  parameterType="int">
    update user set delete_flag=1 where id=#{id}  
</update>

在查询用户时,需要加入对 delete_flag 的判断:

<select  parameterType="int" resultMap="userMap">
    select * from user where id=#{id} and delete_flag=0
</select>

<select  resultMap="userMap">
    select * from user where delete_flag=0
</select>
  1. 使用拦截器,拦截 DELETE 语句并修改为更新语句

这种方式使用拦截器实现,可以自动将 DELETE 语句转换为 UPDATE 语句,并将记录状态修改为已删除状态。

在拦截器中覆盖 Executordelete 方法,在方法中自定义 DELETE 语句的转换,然后调用 update 方法执行修改操作。

在 mapper 的配置文件中,仍然定义 DELETE 语句,但实际执行的操作是 UPDATE 语句:

<delete  parameterType="int">
    delete from user where id=#{id} and delete_flag=0
</delete>

需要注意的是,使用拦截器的方式有一定的风险,需要慎重考虑是否使用,并避免影响到其他的 DELETE 操作。

MyBatis 中,如何处理悲观锁和乐观锁?
在 MyBatis 中,可以使用悲观锁和乐观锁来保证数据的并发安全。

  1. 悲观锁

悲观锁就是在操作数据之前先锁住数据,以防止其他的并发操作。在 MyBatis 中,可以使用以下方式实现悲观锁:

  • 在查询语句中使用 FOR UPDATE,需要手动去申请锁,MyBatis 不会自动去加锁。例如:
<select  resultType="User">
  select * from user where id = #{id} for update
</select>
  • 使用 Mysql 的隐式加行锁,只需要在配置文件中设置对应的参数,例如:
<settings>
  <setting name="cacheEnabled" value="false" />
  <setting name="defaultExecutorType" value="SIMPLE" />
  <setting name="autoMappingBehavior" value="FULL" />
  <setting name="defaultStatementTimeout" value="25000" />
  <setting name="defaultFetchSize" value="100" />
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="true"/>
  <setting name="logImpl" value="LOG4J"/>
  <setting name="mysql" value="true"/>
</settings>
  1. 乐观锁

乐观锁是指在操作数据时,通过版本号或时间戳等方式来判断是否有其他操作并发修改,如果有,则不进行更新操作,否则进行操作。在 MyBatis 中,可以通过以下方式实现乐观锁:

  • 在实体类中增加一个版本字段,用于记录数据更新的版本号或时间戳等信息。例如:
public class User {
  private Long id;
  private String name;
  private int version; // 版本号
  // getter 和 setter 方法
}

在更新操作时,先查询并锁定行,然后比较版本号或时间戳,如果一致则更新数据并增加版本号或时间戳的值,如果不一致则不进行更新。

例如,利用 UPDATE 语句实现乐观锁:

<update  parameterType="User">
  update user
  set name = #{name}, version = #{version} + 1
  where id = #{id} and version = #{version}
</update>

在执行更新操作时,在业务层代码中获取原始数据的版本号或时间戳,然后在执行更新操作时,设置新的版本号或时间戳,并将旧的版本号或时间戳作为更新的条件,判断是否受到并发操作的影响。如果更新失败,则需要处理并发操作失败的情况。

以上就是 MyBatis 中处理悲观锁和乐观锁的方法,可以根据实际需求选择合适的方法。