数据库存储过程实现CRUD

紧接着上篇,这篇主要是实现部门管理,会使用到数据库中的存储过程,什么是存储过程我也会简单介绍。

目录

  • 1.部门管理
    • 1.1.存储过程
    • 1.2.存储过程的调用
    • 1.3.实现功能
    • 1.4.测试

1.部门管理

部门管理实现起来相对于上面的模块还是比较麻烦的,SQL语句麻烦,表结构比较复杂。

部门表结构:

数据库存储过程实现CRUD_第1张图片

  • 分析:在depPath中.1就是父部门的id,默认每个部门的depPath都包括自己的id(股东会的depPath是.1,董事会的父部门是股东会,那么depPath就是.1.2,意思就是财务部属于总办,总办属于董事会,董事会属于股东会。可以看到部门下有子部门的,他的对应isParent都设置为1,反之为0)。细心的同学会看到华东、华南、上海市场部的depPath最前面不是.1而是1,为什么呢?说明他们3个不是直接在股东会下面,这个我们在前端展示的时候就明白了。

  • 难点:假设我们在乌当区市场下面添加一个部门A,添加对应一条SQL语句,添加完之后还没完,添加的时候depPath肯定不会是前端(name,parentId)传过来的,需要我们自己获取,enabledisParent会设置为默认值。部门A的parentId就是乌当区市场的id(插入A之后获取自己的id),这个容易,但是depPath就麻烦了,我们需要根据A的parentId查看乌当区市场的depPath,在其后面再拼接上自己的id,然后我们的乌当区市场的isParent属性从0->1, 所以综上需要的SQL语句较大且繁琐。

为了解决以上的情况,我们使用数据库提供的存储过程来简化业务逻辑处理,可以将上面需要写的那么多条SQL语句理解成一个脚本文件,后端只需调用这个存储过程,存储过程自己会执行脚本,会执行SQL语句,执行完之后会把这个结果返回给后端。

什么是存储过程呢?

1.1.存储过程

MySQL 5.0 版本开始支持存储过程。

存储过程(Stored Procedure)是一种再数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可以通过指定存储过程的名字并给定参数(需要时)来调用执行。

存储过程思想上很简单,就是数据库SQL语句层面的代码封装与重用。通俗来讲:存储过程起始就是能完成一定操作的一组SQL语句。

优点

  • 存储过程可封装,并隐藏复杂的商业逻辑。
  • 存储过程可回传值,也可接受参数。
  • 存储过程无法使用SELECT指令来运行,因为它是子程序,与查看表,数据库或用户定义函数不同。
  • 存储过程可以用在数据检验,强制实行商业逻辑等。

缺点

  • 存储过程往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。
  • 存储过程的性能调校与撰写,受限于各种数据库系统。

1.2.存储过程的调用

  • 存储过程就是具有名字的一段代码,用来完成特定的功能。
  • 创建的存储过程保存在数据库的数据字典中。

1.2.1.调用存储过程

实际项目中使用存储过程就在部门的添加删除,存储过程我一直放在SQL文件中。

数据库存储过程实现CRUD_第2张图片

1.3.实现功能

修改实体类

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);
    }
}

1.4.测试

获取所有部门:

数据库存储过程实现CRUD_第3张图片

添加部门:

数据库存储过程实现CRUD_第4张图片

数据库存储过程实现CRUD_第5张图片

删除部门:

数据库存储过程实现CRUD_第6张图片
到这里我们的部门管理模块就完成了,下一篇博客实现操作员管理模块:


@Data注解,自动生成Getter和Setter方法,与UserDetails中的isEnabled()方法冲突

你可能感兴趣的:(项目练习,Java,spring,boot,后端,mysql,java)