2.1.1 版本新增 LogicalMapper
接口
LogicalMapper
是一个逻辑删除的通用 Mapper,通过 @LogicalColumn
注解实现逻辑删除。这个接口继承 BaseMapper
和 FnMapper
,在 LogicalProvider
中重写了大量方法,如果不符合自己需要可以参考该实现。
public interface LogicalMapper<T, I extends Serializable> extends BaseMapper<T, I>, FnMapper<T> {
/* BaseMapper +++ */
@Override
@Lang(Caching.class)
@UpdateProvider(type = LogicalProvider.class, method = "updateByPrimaryKeySelectiveWithForceFields")
int updateByPrimaryKeySelectiveWithForceFields(@Param("entity") T entity, @Param("fns") Fn.Fns<T> forceUpdateFields);
/* BaseMapper --- */
/* FnMapper +++ */
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "selectColumns")
Optional<T> selectColumnsOne(@Param("entity") T entity, @Param("fns") Fn.Fns<T> selectFields);
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "selectColumns")
List<T> selectColumns(@Param("entity") T entity, @Param("fns") Fn.Fns<T> selectFields);
/* FnMapper --- */
/* EntityMapper +++ */
@Override
@Lang(Caching.class)
@DeleteProvider(type = LogicalProvider.class, method = "deleteByPrimaryKey")
int deleteByPrimaryKey(I id);
@Override
@Lang(Caching.class)
@DeleteProvider(type = LogicalProvider.class, method = "delete")
int delete(T entity);
@Override
@Lang(Caching.class)
@UpdateProvider(type = LogicalProvider.class, method = "updateByPrimaryKey")
int updateByPrimaryKey(T entity);
@Override
@Lang(Caching.class)
@UpdateProvider(type = LogicalProvider.class, method = "updateByPrimaryKeySelective")
int updateByPrimaryKeySelective(T entity);
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "selectByPrimaryKey")
Optional<T> selectByPrimaryKey(I id);
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "select")
Optional<T> selectOne(T entity);
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "select")
List<T> selectList(T entity);
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "selectCount")
long selectCount(T entity);
/* EntityMapper --- */
/* CursorMapper +++ */
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "select")
Cursor<T> selectCursor(T entity);
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "selectByExample")
Cursor<T> selectCursorByExample(Example<T> example);
/* CursorMapper --- */
/* ExampleMapper +++ */
@Override
default Example<T> example() {
return BaseMapper.super.example();
}
@Override
@Lang(Caching.class)
@DeleteProvider(type = LogicalProvider.class, method = "deleteByExample")
int deleteByExample(Example<T> example);
@Override
@Lang(Caching.class)
@UpdateProvider(type = LogicalProvider.class, method = "updateByExample")
int updateByExample(@Param("entity") T entity, @Param("example") Example<T> example);
@Override
@Lang(Caching.class)
@UpdateProvider(type = LogicalProvider.class, method = "updateByExampleSetValues")
int updateByExampleSetValues(@Param("example") Example<T> example);
@Override
@Lang(Caching.class)
@UpdateProvider(type = LogicalProvider.class, method = "updateByExampleSelective")
int updateByExampleSelective(@Param("entity") T entity, @Param("example") Example<T> example);
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "selectByExample")
List<T> selectByExample(Example<T> example);
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "selectByExample")
Optional<T> selectOneByExample(Example<T> example);
@Override
@Lang(Caching.class)
@SelectProvider(type = LogicalProvider.class, method = "countByExample")
long countByExample(Example<T> example);
@Override
List<T> selectByExample(Example<T> example, RowBounds rowBounds);
/* ExampleMapper --- */
}
示例:
public class User {
@Entity.Column(id = true, useGeneratedKeys = true)
private Long id;
@Entity.Column("name")
private String userName;
@Entity.Column
private String sex;
@LogicalColumn(delete = "0")
@Entity.Column(updatable = false, insertable = false)
private Boolean status;
}
逻辑删除查询时过滤删除的数据,对应XML代码如下:
<script>
SELECT
<choose>
<when test="fns != null and fns.isNotEmpty()">
${fns.baseColumnAsPropertyList()}
</when>
<otherwise>
id,name AS userName,sex,status
</otherwise>
</choose>
FROM user
<trim prefix="WHERE" prefixOverrides="WHERE |OR |AND " suffixOverrides="" suffix="">
<if test="_parameter != null">
<where>
<if test="entity.id != null">
AND id = #{entity.id}
</if>
<if test="entity.userName != null">
AND name = #{entity.userName}
</if>
<if test="entity.sex != null">
AND sex = #{entity.sex}
</if>
<if test="entity.status != null">
AND status = #{entity.status}
</if>
</where>
</if>
AND status != 0
</trim>
</script>
WHERE 条件中一定包含 status != 0
。
DELETE 方法变成了 UPDATE:
<script>
UPDATE user SET status = 0
${@io.mybatis.provider.util.Assert@notNull(_parameter, 'Parameter cannot be null')}
<where>
<if test="id != null">
AND id = #{id}
</if>
<if test="userName != null">
AND name = #{userName}
</if>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="status != null">
AND status = #{status}
</if>
AND status != 0
</where>
</script>