紧接着上篇,这篇主要是实现部门管理,会使用到数据库中的存储过程,什么是存储过程我也会简单介绍。
目录
- 1.部门管理
- 1.1.存储过程
- 1.2.存储过程的调用
- 1.3.实现功能
- 1.4.测试
部门管理实现起来相对于上面的模块还是比较麻烦的,SQL语句麻烦,表结构比较复杂。
部门表结构:
分析:在depPath中.1
就是父部门的id,默认每个部门的depPath都包括自己的id(股东会的depPath是.1,董事会的父部门是股东会,那么depPath就是.1.2
,意思就是财务部属于总办,总办属于董事会,董事会属于股东会。可以看到部门下有子部门的,他的对应isParent
都设置为1,反之为0)。细心的同学会看到华东、华南、上海市场部的depPath最前面不是.1
而是1
,为什么呢?说明他们3个不是直接在股东会下面,这个我们在前端展示的时候就明白了。
难点:假设我们在乌当区市场下面添加一个部门A,添加对应一条SQL语句,添加完之后还没完,添加的时候depPath
肯定不会是前端(name,parentId)传过来的,需要我们自己获取,enabled
和isParent
会设置为默认值。部门A的parentId就是乌当区市场的id(插入A之后获取自己的id),这个容易,但是depPath
就麻烦了,我们需要根据A的parentId查看乌当区市场的depPath
,在其后面再拼接上自己的id,然后我们的乌当区市场的isParent
属性从0->1, 所以综上需要的SQL语句较大且繁琐。
为了解决以上的情况,我们使用数据库提供的存储过程
来简化业务逻辑处理,可以将上面需要写的那么多条SQL语句理解成一个脚本文件,后端只需调用这个存储过程,存储过程自己会执行脚本,会执行SQL语句,执行完之后会把这个结果返回给后端。
什么是存储过程呢?
MySQL 5.0 版本开始支持存储过程。
存储过程(Stored Procedure)是一种再数据库中存储复杂程序,以便外部程序调用的一种数据库对象。
存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可以通过指定存储过程的名字并给定参数(需要时)来调用执行。
存储过程思想上很简单,就是数据库SQL语句层面的代码封装与重用。通俗来讲:存储过程起始就是能完成一定操作的一组SQL语句。
优点
缺点
1.2.1.调用存储过程
实际项目中使用存储过程就在部门的添加
和删除
,存储过程我一直放在SQL文件中。
修改实体类
Department.java
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_department")
@ApiModel(value="Department对象", description="")
public class Department implements Serializable {
......
@ApiModelProperty(value = "是否上级")
private Boolean isParent;
@ApiModelProperty(value = "子部门列表")
@TableField(exist = false)
private List<Department> children;
@ApiModelProperty(value = "返回结果,存储过程使用")
@TableField(exist = false)
private Integer result;
}
1.3.1.Mapper层
public interface DepartmentMapper extends BaseMapper<Department> {
/**
* 获取所有部门
* @param parentId
* @return
*/
List<Department> getAllDepartments(Integer parentId);
/**
* 添加部门
* @param department
*/
void addDep(Department department);
/**
* 删除部门
* @param department
*/
void deleteDep(Department department);
}
1.3.2.服务类
IDepartmentService.java
public interface IDepartmentService extends IService<Department> {
/**
* 获取所有部门
* @return
*/
List<Department> getAllDepartments();
/**
* 添加部门
* @param department
* @return
*/
RespBean addDep(Department department);
/**
* 删除部门
* @param id
* @return
*/
RespBean deleteDep(Integer id);
}
1.3.3.服务实现类
DepartmentServiceImpl.java
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements IDepartmentService {
@Resource
private DepartmentMapper departmentMapper;
@Override
public List<Department> getAllDepartments() {
return departmentMapper.getAllDepartments(-1);
}
@Override
public RespBean addDep(Department department) {
department.setEnabled(true);
departmentMapper.addDep(department);
if (1 == department.getResult()) {
return RespBean.success("添加成功!", department);
}
return RespBean.error("添加失败");
}
@Override
public RespBean deleteDep(Integer id) {
Department department = new Department();
department.setId(id);
departmentMapper.deleteDep(department);
if (1 == department.getResult()) {
return RespBean.success("删除成功!");
}
if (-2 == department.getResult()) {
return RespBean.error("该部门下有子部门,删除失败");
}
if (-1 == department.getResult()) {
return RespBean.error("该部门下有员工,删除失败");
}
return RespBean.error("删除失败");
}
}
1.3.4.映射文件
DepartmentMapper.xml
<resultMap id="DepartmentWithChildren" type="com.kt.pojo.Department" extends="BaseResultMap">
<collection property="children" ofType="com.kt.pojo.Department"
select="com.kt.mapper.DepartmentMapper.getAllDepartments"
column="id">
collection>
resultMap>
<select id="deleteDep" statementType="CALLABLE">
call deleteDep(#{id, mode=IN, jdbcType=INTEGER}, #{result, mode=OUT, jdbcType=INTEGER})
select>
<select id="addDep" statementType="CALLABLE">
call addDep(#{name, mode=IN, jdbcType=VARCHAR}, #{parentId, mode=IN, jdbcType=VARCHAR}, #{enabled, mode=IN, jdbcType=BOOLEAN}, #{result, mode=OUT, jdbcType=INTEGER}, #{id, mode=OUT, jdbcType=INTEGER})
select>
<select id="getAllDepartments" resultMap="DepartmentWithChildren">
select
<include refid="Base_Column_List"/>
from t_department
where parentId = #{parentId}
select>
1.3.5.控制层
DepartmentController.java
@RestController
@RequestMapping("/system/basic/department")
public class DepartmentController {
@Resource
private IDepartmentService departmentService;
@ApiOperation(value = "获取所有部门")
@GetMapping("/")
public List<Department> getAllDepartment() {
return departmentService.getAllDepartments();
}
@ApiOperation(value = "添加部门")
@PostMapping("/")
public RespBean addDep(@RequestBody Department department) {
return departmentService.addDep(department);
}
@ApiOperation(value = "删除部门")
@DeleteMapping("/{id}")
public RespBean deleteDep(@PathVariable Integer id) {
return departmentService.deleteDep(id);
}
}
获取所有部门:
添加部门:
删除部门:
到这里我们的部门管理模块就完成了,下一篇博客实现操作员管理模块:
@Data注解,自动生成Getter和Setter方法,与UserDetails中的isEnabled()方法冲突