上个小节我们调通了修改角色信息的功能,那么这节课我们来写删除角色记录的后端Java代码。注意,系统内置角色是不能删除的,一旦删除会影响到工作流程序。比如说员工请假需要部门经理审批,如果你把部门经理角色删除了,那么谁来审批员工请假呢?所以我们只能删除非内置的角色,而且是那种没有关联任何用户的角色才能被删除,关联了用户的角色是不能删除的。
一、编写持久层代码
在TbRoleDao.xml
文件中,定义两个SQL语句。
<select id="searchCanDelete" resultType="boolean">
SELECT IF( SUM( temp.users ) > 0, FALSE, TRUE ) AS result FROM (
SELECT COUNT( u.id ) AS users
FROM tb_role r
JOIN tb_user u ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
WHERE r.id IN
<foreach collection="array" open="(" separator="," close=")" item="one">
#{one}
</foreach>
GROUP BY r.id
) temp
</select>
<delete id="deleteRoleByIds">
DELETE FROM tb_role
WHERE id IN
<foreach collection="array" open="(" separator="," close=")" item="one">
#{one}
</foreach>
AND systemic=FALSE
</delete>
我先来说一下searchCanDelete
这个SQL语句,这个SQL语句很不好理解没关系,我告诉你他的原理是什么。我用几个简单的SQL语句,来告诉你复杂的SQL语句是怎么进化来的。例如下面的SQL语句是分组查询每种角色的用户数量。
SELECT COUNT( u.id ) AS users
FROM tb_role r
JOIN tb_user u ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
WHERE r.id IN (1,2,4)
GROUP BY r.id;
SQL语句运行结果如下:
如果我们把上面的SQL语句查询的结果当做一张临时表,统计求和是否大于零。如果大于零,说明你要删除的这些角色中,有关联用户的角色。大家仔细想想,用户在前端页面勾选了若干角色,想要删除这些角色。后端只要盘判定出这些角色,无论哪一个只要存在关联的用户,那么这些要删除的角色一律不许删除。除非我们统计求和的结果是零,说明这些要删除的角色都没有关联用户,这些角色允许删除。
SELECT IF( SUM( temp.users ) > 0, FALSE, TRUE ) AS result FROM (
SELECT COUNT( u.id ) AS users
FROM tb_role r
JOIN tb_user u ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
WHERE r.id IN (1,2,4)
GROUP BY r.id
) temp;
SQL运行的结果如下:
由于MySQL中的FALSE用数字零表示,所以SQL语句查询出来我想要删除的3个角色存在关联的用户。现在大家再去看看searchCanDelete
这个SQL语句,估计就能看懂了。另外,deleteRoleByIds
这个SQL语句中WHERE子句的条件写的很清楚,只能删除非内置的角色。
在TbRoleDao.java
接口中,定义DAO方法。
public interface TbRoleDao {
……
public boolean searchCanDelete(Integer[] ids);
public int deleteRoleByIds(Integer[] ids);
}
二、编写业务层代码
在RoleService.java
接口中,定义抽象方法。
public interface RoleService {
……
public int deleteRoleByIds(Integer[] ids);
}
在RoleServiceImpl.java
类中,实现抽象方法,其中就有判定角色是否能删除。
public class RoleServiceImpl implements RoleService {
……
@Override
public int deleteRoleByIds(Integer[] ids) {
if (!roleDao.searchCanDelete(ids)) {
throw new EmosException("无法删除关联用户的角色");
}
int rows = roleDao.deleteRoleByIds(ids);
return rows;
}
}
三、编写Web层代码
创建DeleteRoleByIdsForm.java
类,封装Ajax提交的数据。
@Data
@Schema(description = "删除角色表单")
public class DeleteRoleByIdsForm {
@NotEmpty(message = "ids不能为空")
@Schema(description = "角色ID")
private Integer[] ids;
}
在RoleController.java
类中,声明Web方法,然后大家可以用Swagger测试一下。
public class RoleController {
……
@PostMapping("/deleteRoleByIds")
@Operation(summary = "删除角色记录")
@SaCheckPermission(value = {"ROOT", "ROLE:DELETE"}, mode = SaMode.OR)
public R deleteRoleByIds(@Valid @RequestBody DeleteRoleByIdsForm form) {
int rows = roleService.deleteRoleByIds(form.getIds());
return R.ok().put("rows", rows);
}
}