1、问题
开发的接口前端调用时删除报错,怎么删除都提示删除不成功,刚开始以为是方法不对。
2、场景
若依框架下使用 mybatis-plus 的批量删除方法,删除接口报错,第一次点击删除,显示删除成功,但是列表仍然存在,之后点击显示删除失败。
3、原因
经过前后端联调,如下图发现如下,list接口中"delFlag":"1"
,
也就是执行删除方法时使用的是软删除把"delFlag"值改为了"1",并没有把实际数据删除,导致我很疑惑?????????????????????????????
为啥是调用的软删除待查
经过排查发现 @TableLogic 注解这里出了问题,由于实体类代码是生成的,字段上加了个 @TableLogic 注解,此时调用删除方法实际是调用更新方法也就是将"delFlag"值更新为了"1"。
软删除和硬删除最大的区别应该是是否真的删除了,软删除应该是没有真正删除,依然存在硬盘里,可以找回。
具体代码
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(xxxRoleService.removeByIds(Arrays.asList(ids)));
}
mybatis-plus源码
/**
* 删除(根据ID 批量删除)
*
* @param idList 主键ID列表
*/
default boolean removeByIds(Collection<? extends Serializable> idList) {
if (CollectionUtils.isEmpty(idList)) {
return false;
}
return SqlHelper.retBool(getBaseMapper().deleteBatchIds(idList)); //SqlHelper是sql辅助类
}
retBool方法
/**
* 判断数据库操作是否成功
*
* @param result 数据库操作返回影响条数
* @return boolean
*/
public static boolean retBool(Integer result) {
return null != result && result >= 1;
}
于是反应到查询接口是否查询时的问题
<sql id="selectxxxRoleVo">
select id, name, xxx,xxx, del_flag, xxxxxxxxxxxxxxxx from xxx_role
</sql>
<select id="selectxxxxRoleList" parameterType="xxxxRole" resultMap="xxxxRoleResult">
<include refid="selectxxxRoleVo"/>
<where>
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
<if test="enname != null and enname != ''"> and enname like concat('%', #{enname}, '%')</if>
</where>
</select>
4、解决方案
查询条件中添加 del_flag="0"如下,解决此问题。
<sql id="selectxxxRoleVo">
select id, name, xxx,xxx, del_flag, xxxxxxxxxxxxxxxx from xxx_role
</sql>
<select id="selectxxxxRoleList" parameterType="xxxxRole" resultMap="xxxxRoleResult">
<include refid="selectxxxRoleVo"/>
<where>
del_flag="0"
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
<if test="enname != null and enname != ''"> and enname like concat('%', #{enname}, '%')</if>
</where>
</select>
当然也涨了个教训,注意查看数据库中的字段,如果有 del_flag ,查询列表时时就要注意一下了。
5、思考
冲浪查询问题看到
MyBatis-Plus使用removeByIds批量删除太慢导致mysql锁定
待补充思考
所有评论(0)