员工管理系统案例

员工管理系统

这是一个综合了前后端、开发流程比较完整的一个简单管理系统。项目中已经提供好了前端页面,但是还需要我们自己去编写后端返回给前端的请求。

其中需要编写的请求就是增删改查这四个基础的请求。在这个项目中,总共有两个需要创建的表,即员工表和部门表。所有的增删查改任务都是基于这两张表来开展的。

RestAPI风格

与传统的GETPOST请求不同,RestAPI把每项不同的操作划分给不同的动作

  • GET

    可以只负责查询数据

  • POST

    可以负责新增数据

  • PUT

    可以负责修改数据

  • Delete

    可以负责删除数据

单单从url里面来说,这四种操作的url几乎相同,只是行为不同,这样就使得更加规范

项目工程结构

工程的结构总共分为几大类

  • Controller

    专门负责处理来自前端的数据

  • Mapper

    专门负责处理来自数据库的部分

  • Service

    负责业务逻辑,如调用来自Mapper的接口,拿到数据库里面的数据后进行各种处理。

  • Pojo

    负责存放一些实体类,如表里面的EmpUser对象等。

查询数据

项目中有一个功能就是去实现目前所有部门,用sql语句来表示可能就是

1
select name, create_time, update_time from dep;

让我们先来熟悉一下思路

  • Mapper

    Mapper层需要定义查询数据库的接口,因为查询sql很简短,所以我们可以直接写在java代码里面。

    1
    2
    3
    4
    5
    
    @Mapper
    public interface DeptMapper {
        //查询所有部门数据
        @Select("select id, name, create_time, update_time from dept")
        List<Dept> list();
    

    Mapper是开启容器化注入的一个注解,其实很简单,需要实现对部门的任何操作都可以写在这个DeptMapper当中。

  • Service

    然后我们需要在Service层获取在Mapper层得到的来自数据库的信息。在service层中,我们定义了Dept接口和DeptImpl实现对象,在这里可以编写对应的方法来获取得到的数据库对象

    1
    2
    3
    4
    5
    6
    
    @Autowired
    private DeptMapper deptMapper;
    @Override
    public List<Dept> list() {
        return deptMapper.list();
    }
    
  • Controller

    controller中调用Service层处理好的数据,然后经过统一的响应格式(Result)返回

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    @Autowired
    private DeptService deptService;
    
    //@RequestMapping(value = "/depts" , method = RequestMethod.GET)
    @GetMapping
    public Result list(){
        List<Dept> deptList = deptService.list();
        return Result.success(deptList);
    }
    

    需要注意的是,在填写url时,我们可以直接指定访问该url的动作,即使用GET方法即可

    1
    2
    3
    4
    5
    
    @GetMapping
    public Result list(){
        List<Dept> deptList = deptService.list();
        return Result.success(deptList);
    }
    

这就是查询数据的操作。

增加数据

增加一条数据的sql原语句就是

1
insert into dep(字段名) values()

在部门字段中,如果我们需要新添加一个部门,那么在前端页面上只需要输入其姓名即可,然而这个部门包含以下几个属性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mysql> desc dept;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int unsigned | NO   | PRI | NULL    | auto_increment |
| name        | varchar(10)  | NO   | UNI | NULL    |                |
| create_time | datetime     | NO   |     | NULL    |                |
| update_time | datetime     | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

其中,后面两个字段需要在我们成功创建对象的时候就添加为创建时的时间now(),而如何传递name字段呢,其实在前端向后端传递数据时,其传递的数据就是json的键值对,我们可以利用RequestBody这个属性来填写该字段,并把该字段的create_timeupdate_time更新为创建时的时间即可。

1
2
3
4
// 新增部门
// 需要注意的是后面的参数是来自我们自己封装的Dept对象,所以后面要用驼峰命名法,即和dept里面的数据名一致
@Insert("insert into dept(name, create_time, update_time) values (#{name}, #{createTime}, #{updateTime})")
void insert(Dept dept);

需要注意的是,在pojo.Dept中,后面两个字段都是按照驼峰命名法来命名的,而数据库中的变量是以下划线来进行分割的,这里有一个变量名转换依赖,在使用这个依赖后就可以将我们的字段成功转换。

为了防止我以后看到这段代码疑惑,数值在代码中传递的方向是

  • Controller

    获取name,并添加时间字段

  • Service

    将这个数据传递到Service层中

  • Mapper

    再传递到Mapper中,然后插入数据。

显然,在数据流动过程中,如果需要执行查询等这类不需要修改数据库的内容,那么数据就是从数据库出发,返回到controller后完成响应。

如果需要执行删除、修改等这类的操作,那么数据就是从controller层出发,传递到数据库后,完成响应。

删除数据

同样的,在Mapper层中定义好删除接口,在Service层中实现逻辑,然后在Controller层中完成响应

1
2
3
// 根据id来删除
@Delete("delete from dept where id = #{id}")
void delete(int id);

修改数据

可以根据传进来的id来实现修改部门

1
2
3
4
5
6
@PutMapping("{id}")
public Result update(@RequestBody Dept dept){
    dept.setUpdateTime(LocalDateTime.now());
    deptService.update(dept);
    return Result.success();
}

Service

1
2
3
4
@Override
public void update(Dept dept) {
    deptMapper.update(dept);
}

Mapper

1
2
3
// 修改数据
@Update("update dept set name = #{name}, update_time = #{updateTime} where id = #{id}")
void update(Dept dept);

总结

这里实现了基本的增删查改功能。现在我们来梳理以下这样一个前后端项目需要哪些条件。

环境搭建

  • 准备好数据库连接

  • 分包编写代码。在Mapper层中编写操作数据库有关的代码;在Service层实现业务逻辑;在Controller层实现响应。

  • Mapper层中都是接口对象,下面是一个包目录的文件结构

    image-20250309215340894

Licensed under CC BY-NC-SA 4.0
花有重开日,人无再少年
使用 Hugo 构建
主题 StackJimmy 设计