vhr部门管理数据库设计与编程
项目地址:https://github.com/lenve/vhr
好了,那我们本文主要来看看数据库的设计与存储过程的编写。
部门数据库整体来说还是比较简单,如下:
都是常规字段,脚本可以在项目中下载。depPath是为了查询方便,isParent表示该条是否是父部门。为了简化程序中的逻辑,depPath的设置和isParent的设置我都在存储过程中完成。
添加部门存储过程
添加部门存储过程如下:
DELIMITER $$
USE `vhr`$$
DROP PROCEDURE IF EXISTS `addDep`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `addDep`(in depName varchar(32),in parentId int,in enabled boolean,out result int,out result2 int)
begin
declare did int;
declare pDepPath varchar(64);
insert into department set name=depName,parentId=parentId,enabled=enabled;
select row_count() into result;
select last_insert_id() into did;
set result2=did;
select depPath into pDepPath from department where id=parentId;
update department set depPath=concat(pDepPath,'.',did) where id=did;
update department set isParent=true where id=parentId;
end$$
DELIMITER ;
关于这个存储过程,我说如下几点:
1.该存储过程接收五个参数,三个输入参数分别是部门名称、父部门Id,该部门是否启用,两个输出参数分别表示受影响的行数和插入成功后id的值。
2.存储过程首先执行插入操作,插入完成后,将受影响行数赋值给result。
3.然后通过last_insert_id()
获取刚刚插入的id,赋给result2。
4.接下来查询父部门的depPath,并且和刚刚生成的id组合后作为刚刚插入部门的depPath。
5.将父部门的isParent字段更新为true。
将这些逻辑写在存储过程中,可以简化我们代码中的逻辑。
删除部门存储过程
删除部门也被我写成了存储过程,主要是因为删除过程也要做好几件事,核心代码如下:
DELIMITER $$
USE `vhr`$$
DROP PROCEDURE IF EXISTS `deleteDep`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `deleteDep`(in did int,out result int)
begin
declare ecount int;
declare pid int;
declare pcount int;
select count(*) into ecount from employee where departmentId=did;
if ecount>0 then set result=-1;
else
select parentId into pid from department where id=did;
delete from department where id=did and isParent=false;
select row_count() into result;
select count(*) into pcount from department where parentId=pid;
if pcount=0 then update department set isParent=false where id=pid;
end if;
end if;
end$$
DELIMITER ;
关于这个存储过程,我说如下几点:
1.一个输入参数表示要删除数据的id,一个输出参数表示删除结果。
2.如果该部门下有员工,则该部门不能被删除。
3.删除该部门时注意加上条件isParent=false,即父部门不能被删除,这一点我在前端已经做了判断,正常情况下父部门的删除请求不会被发送,但是考虑到前端的数据不能被信任,所以后台我们也要限制。
4.删除成功之后,查询删除部门的父部门是否还有其他子部门,如果没有,则将父部门的isParent修改为false。
其他一些琐碎的技术就不值得介绍了,大家在源码中自行研究,有问题欢迎留言讨论。
- Python机器学习工具:Scikit-Learn介绍与实践
- (51) 剖析EnumSet / 计算机程序的思维逻辑
- mysql性能优化的几条重要建议
- Python爬虫抓取知乎所有用户信息
- Eclipse远程调试出现“JDWP Transport dt_socket failed to initialize”的解决方案
- Django 博客教程:前言和环境安装(连载一)
- (52) 抽象容器类 / 计算机程序的思维逻辑
- mysql的查询、子查询及连接查询
- 简陋的分布式爬虫(附项目代码地址)
- 使用PowerShell简化我的工作
- 几个提高工作效率的Python内置小工具
- J2EE相关总结
- (53) 剖析Collections - 算法 / 计算机程序的思维逻辑
- Flask使用Blueprint进行多模块应用的编写
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- AndroidX下使用Activity和Fragment的变化详解
- PHP Primary script unknown 解决方法总结
- PHP如何将图片文件上传到另外一台服务器上
- android实现滑动解锁
- laravel框架模板之公共模板、继承、包含实现方法分析
- Android项目实战之百度地图地点签到功能
- PHP Redis扩展无法加载的问题解决方法
- PHP 文件上传限制问题
- Flutter permission_handler 权限插件的使用详解
- Flutter使用JsBridge方式处理Webview与H5通信的方法
- flutter 怎么实现app整体灰色效果
- 解决android studio中使用monitor工具无法打开data文件夹问题
- Android安装应用 INSTALL_FAILED_DEXOPT 问题及解决办法
- php简单检测404页面的方法示例
- thinkPHP3.2使用RBAC实现权限管理的实现