【mybatis-plus】mybatis-plus 删除并自动填充

mybatis-plus中做逻辑删除是 只是简单的修改逻辑删除的字段, 如果想要在删除的同时添加删除人,和删除时间该如何实现呢?对于填充数据 我们可以使用 mybatis-plus的自动填充功能

但是不是所有的删除都会触发自动填充功能

在mybatis-plus老版本中 删除是不能触发自动填充的
需要使用官方的Sql 注入器LogicDeleteByIdWithFill 而且调用方法为deleteByIdWithFill
在这里不具体赘述了

@Component
public class MySqlInjector extends DefaultSqlInjector {
	@Override
	public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
		List<AbstractMethod> methods = super.getMethodList(mapperClass, tableInfo);
		methods.add(new LogicDeleteByIdWithFill());
		return methods;
	}
}

在新版本中 deleteById 默认实现了自动填充,不需要用户再手动添加sql注入器

在这里插入图片描述
如上图 mybatis源码中我们可以看出, 我们在使用deleteById(Entity et) 时,就可以触发自动填充
可是这也不能适用所有场景,deleteById 虽然可以实现填充的效果,但是where筛选只会根据id进行删除.
如果某些业务里面需要添加其他删除条件时无法实现了.所以我们要自己写一个sql注入器

第一步 编写注入器,这里面注意MAPPER_METHOD 是mapper中定义的方法名 ,名称随意保持一致就行

public class LogicDeleteWithFill extends AbstractMethod {

	/**
	 * mapper 对应的方法名
	 */
	private static final String MAPPER_METHOD = "deleteWithFill";

	private static final long serialVersionUID = -402373469518227818L;

	@Override
	public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
		String sql;
		SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE;
		if (tableInfo.isWithLogicDelete()) {
			List<TableFieldInfo> fieldInfos = tableInfo.getFieldList().stream()
					.filter(i -> i.getFieldFill() == FieldFill.UPDATE || i.getFieldFill() == FieldFill.INSERT_UPDATE)
					.collect(toList());
			if (CollectionUtils.isNotEmpty(fieldInfos)) {
				String sqlSet = "SET " + fieldInfos.stream().map(i -> i.getSqlSet(ENTITY_DOT)).collect(joining(EMPTY))
						+ tableInfo.getLogicDeleteSql(false, false);
				sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlSet,
						sqlWhereEntityWrapper(true, tableInfo), sqlComment());
			}
			else {
				sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlLogicSet(tableInfo),
						sqlWhereEntityWrapper(true, tableInfo), sqlComment());
			}
			SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
			return addUpdateMappedStatement(mapperClass, modelClass, MAPPER_METHOD, sqlSource);
		}
		else {
			sqlMethod = SqlMethod.DELETE;
			sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
			SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
			return addDeleteMappedStatement(mapperClass, MAPPER_METHOD, sqlSource);
		}
	}


}

第二步 注册注入器

@Component
public class MySqlInjector extends DefaultSqlInjector {

	@Override
	public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
		List<AbstractMethod> methods = super.getMethodList(mapperClass, tableInfo);
		methods.add(new LogicDeleteWithFill());
		return methods;
	}

}

第三步 在mapper中添加方法
只要在你的mapper中添加这个方法即可 不需要为该方法添加xml方法
注意这里的方法名要和sql注入器中的MAPPER_METHOD 保持一致
实体类类型与所在mapper保持一致(该例中的Dictionary)
完成这一步 就可以正常使用了

public interface DictionaryMapper extends BaseMapper<Dictionary> {

	/**
	 * 删除并自动填充
	 *
	 * @param param   实体类
	 * @param wrapper 删除条件
	 * @return 删除影响条数
	 * @since 2021/11/15 13:54
	 */
	int deleteWithFill(@Param(Constants.ENTITY) Dictionary param, @Param(Constants.WRAPPER) Wrapper<Dictionary> wrapper);

}

测试
在这里插入图片描述
sql打印
在这里插入图片描述

优化 (可有可无) 为了方便使用 可以创建自己的service serviceImpl mapper
这样就不需要在每个mapper接口中添加 deleteWithFill 方法了

mapper 接口
public interface MyBaseMapper<T extends BaseEntity> extends BaseMapper<T> {

	/**
	 * 批量删除并填充数据
	 *
	 * @param param   实体类
	 * @param wrapper 删除条件
	 * @return 删除影响条数
	 * @since 2021/11/15 13:54
	 */
	int deleteWithFill(@Param(Constants.ENTITY) T param, @Param(Constants.WRAPPER) Wrapper<T> wrapper);

}
service 接口
public interface MyService<T extends BaseEntity> extends IService<T> {

	/**
	 * 批量删除数据
	 *
	 * @param t      实体类
	 * @param idList id 集合
	 * @return 执行结果
	 * @author jzw
	 * @since 2021/11/15 14:05
	 */
	boolean batchDelete(List<Long> idList, T t);

	/**
	 * 删除数据
	 *
	 * @param t       实体类
	 * @param wrapper 删除条件
	 * @return 执行结果
	 * @author jzw
	 * @since 2021/11/15 14:05
	 */
	boolean deleteWithFill(T t, Wrapper<T> wrapper);

}

serviceImpl 实现类
public class MyServiceImpl<M extends MyBaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> implements MyService<T> {

		/**
	 * 批量删除数据
	 *
	 * @param t      实体类
	 * @param idList id 集合
	 * @return 执行结果
	 * @author jzw
	 * @since 2021/11/15 14:05
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean batchDelete(List<Long> idList, T t) {
		return deleteWithFill(t, new LambdaQueryWrapper<>(t).in(T::getId, idList));
	}

	/**
	 * 删除数据
	 *
	 * @param t       实体类
	 * @param wrapper 删除条件
	 * @return 执行结果
	 * @author jzw
	 * @since 2021/11/15 14:05
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteWithFill(T t, Wrapper<T> wrapper) {
		return SqlHelper.retBool(baseMapper.deleteWithFill(t, wrapper));
	}
}
实体父类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseEntity implements Serializable {

	private static final long serialVersionUID = -3925407267780334782L;

	/**
	 *
	 */
	private Long id;

	/**
	 * 创建人
	 */
	@JsonInclude(Include.NON_NULL)
	@TableField(fill = FieldFill.INSERT)
	private Long createId;

	/**
	 * 创建时间
	 */
	@JsonInclude(Include.NON_NULL)
	@TableField(fill = FieldFill.INSERT)
	private LocalDateTime createTime;

	/**
	 * 更新人
	 */
	@JsonIgnore
	@TableField(fill = FieldFill.INSERT_UPDATE, select = false)
	private Long updateId;

	/**
	 * 更新时间
	 */
	@JsonIgnore
	@TableField(fill = FieldFill.INSERT_UPDATE, select = false)
	private LocalDateTime updateTime;

	/**
	 * 逻辑删除
	 */
	@JsonIgnore
	private Boolean deleted;

}

业务模块继承自定义的即可

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鲸渔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值