Featured image of post 如何实现简单的员工删除功能

如何实现简单的员工删除功能

2309字

如何实现简单的员工删除功能

内容概览:

  • 删除员工功能 - 支持批量删除
  • 修改员工功能 - 查询回显 + 数据更新
  • 异常处理机制 - 全局异常处理器
  • 员工信息统计 - 职位统计 + 性别统计

1. 批量删除员工功能

1.1 需求分析

  • 支持单个 / 批量删除员工(通过 ID 列表操作)
  • 需同时删除员工基本信息(emp表)和相关工作经历(emp_expr表)
  • 业务规则:确保主从表数据一致性,通过事务保证原子性

1.2 核心代码实现

Controller 层

  • 方法一:用数组
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@RestController
@RequestMapping("/emps")
public class EmpController {
    @DeleteMapping  
	public Result delete(Integer[] ids){  
		log.info("员工删除: {}",Arrays.toString(ids));  
		//调用service层代码略
		return Result.success();  
}
}
  • 方法二:用List集合(建议)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@RestController
@RequestMapping("/emps")
public class EmpController {
    @DeleteMapping
    public Result delete(@RequestParam("ids") List<Integer> ids) {
        log.info("执行批量删除:ids={}", ids);
        empService.deleteByIds(ids);
        return Result.success();
    }
}

Service 层(事务控制)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
@Service
public class EmpServiceImpl implements EmpService {
    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private EmpExprMapper empExprMapper;

    @Override
    @Transactional // 声明式事务管理
    public void deleteByIds(List<Integer> ids) {
        // 1. 删除员工基本信息
        empMapper.deleteByIds(ids);
        // 2. 删除关联的工作经历
        empExprMapper.deleteByEmpIds(ids);
    }
}

Mapper 层(MyBatis 动态 SQL)

xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<!-- empMapper.xml -->
<delete id="deleteByIds">
    DELETE FROM emp 
    WHERE id IN 
    <!-- 遍历ids集合,生成IN条件 -->
    <foreach collection="ids" item="id" open="(" close=")" separator=",">  
        #{id}  <!-- 插入当前id值 -->
    </foreach>
</delete>

<!-- empExprMapper.xml -->
<delete id="deleteByEmpIds">
    DELETE FROM emp_expr 
    WHERE emp_id IN 
    <foreach collection="empIds" item="empId" open="(" close=")" separator=",">  <!-- 遍历empIds集合,生成IN条件 -->
        #{empId}  <!-- 插入当前empId值 -->
    </foreach>
</delete>

2. 修改员工功能

2.1 查询回显实现(复杂结果集映射)

数据库表关联查询

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<resultMap id="empWithExprResultMap" type="Emp">
    <!-- 主表字段映射 -->
    <id column="emp_id" property="id" />
    <result column="username" property="username" />
    <result column="name" property="name" />
    <!-- 一对多关联:工作经历列表 -->
    <collection property="exprList" ofType="EmpExpr">
        <id column="expr_id" property="id" />
        <result column="company" property="company" />
        <result column="start_time" property="startTime" />
        <result column="end_time" property="endTime" />
    </collection>
</resultMap>

<select id="getEmpById" resultMap="empWithExprResultMap">
    SELECT 
        e.id AS emp_id,
        e.username,
        e.name,
        ee.id AS expr_id,
        ee.company,
        ee.start_time,
        ee.end_time
    FROM emp e
    LEFT JOIN emp_expr ee ON e.id = ee.emp_id
    WHERE e.id = #{id}
</select>

2.2 更新员工实现(动态 SQL + 事务)

i示意图 resultType和resultMap

主表动态更新

xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<update id="updateEmp">
    UPDATE emp
    <set>
        <if test="username != null">username = #{username},</if>
        <if test="name != null">name = #{name},</if>
        <if test="gender != null">gender = #{gender},</if>
        update_time = NOW()
    </set>
    WHERE id = #{id}
</update>

Service 层事务逻辑

java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@Override
@Transactional
public void updateEmp(Emp emp) {
    // 1. 更新基本信息
    empMapper.updateEmp(emp);
    // 2. 先删除旧工作经历
    empExprMapper.deleteByEmpId(emp.getId());
    // 3. 新增新工作经历(如果有)
    if (!CollectionUtils.isEmpty(emp.getExprList())) {
        emp.getExprList().forEach(expr -> expr.setEmpId(emp.getId()));
        empExprMapper.insertBatch(emp.getExprList());
    }
}

3. 全局异常处理机制

3.1 统一异常处理器

java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 处理所有未捕获异常
    @ExceptionHandler(Exception.class)
    public Result<String> handleGlobalException(Exception ex) {
        log.error("全局异常:{}", ex.getMessage(), ex);
        return Result.error("服务器内部错误,请联系管理员");
    }

    // 处理数据库唯一约束异常(如手机号重复)
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public Result<String> handleDuplicateException(SQLIntegrityConstraintViolationException ex) {
        if (ex.getMessage().contains("Duplicate entry")) {
            return Result.error("数据已存在,请勿重复提交");
        }
        return Result.error("数据库操作失败");
    }

    // 处理业务校验异常
    @ExceptionHandler(BusinessException.class)
    public Result<String> handleBusinessException(BusinessException ex) {
        return Result.error(ex.getMessage());
    }
}

4. 员工信息统计功能

4.1 职位统计(SQL 分组 + 数据转换)

Mapper 层统计 SQL

xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<select id="countJobStatistics" resultType="map">
    SELECT
        CASE job 
            WHEN 1 THEN '班主任'
            WHEN 2 THEN '讲师'
            ELSE '其他职位' 
        END AS position,
        COUNT(*) AS count
    FROM emp
    GROUP BY job
    ORDER BY count DESC
</select>

Service 层数据封装

java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public Map<String, Object> getJobStatistics() {
    List<Map<String, Object>> list = empMapper.countJobStatistics();
    List<String> positions = list.stream().map(m -> (String) m.get("position")).collect(Collectors.toList());
    List<Integer> counts = list.stream().map(m -> (Integer) m.get("count")).collect(Collectors.toList());
    
    return new HashMap<>() {{
        put("labels", positions);
        put("data", counts);
    }};
}

4.2 性别统计(使用 IF 函数分组)

Mapper 层统计 SQL

xml

1
2
3
4
5
6
7
<select id="countGenderStatistics" resultType="map">
    SELECT
        IF(gender = 1, '男', '女') AS gender,
        COUNT(*) AS count
    FROM emp
    GROUP BY gender
</select>

返回结果示例

json

1
2
3
4
{
  "gender": ["男", "女"],
  "count": [15, 8]
}

🎯 关键知识点总结

1. 批量操作处理

  • MyBatis 技巧:使用<foreach>标签实现 IN 条件,collection属性支持List/Array
  • 参数传递:Controller 层需用@RequestParam("ids")接收数组参数

2. 复杂结果映射

  • 一对多关联:通过<collection>标签映射主从表关系,需使用别名避免字段冲突
  • 性能优化:使用LEFT JOIN保留主表数据,即使从表无记录也能正常回显

3. 事务管理要点

  • 注解范围@Transactional应添加在 Service 层方法上,而非 Mapper 层
  • 操作顺序:更新关联数据时建议先删除旧数据再插入新数据,避免唯一键冲突

4. 异常处理最佳实践

  • 分层处理:区分业务异常(BusinessException)和技术异常(数据库异常)
  • 友好提示:对唯一性约束异常等特定场景返回明确错误信息,避免暴露数据库细节

5. 统计查询技巧

  • 数据转换:使用CASE WHENIF函数将数据库枚举值转换为前端展示文本
  • 结果适配:将统计结果封装为{labels, data}格式,直接对接 ECharts 等图表组件

🚦 联调测试要点

1. 批量删除测试

  • 单条测试:传入单个 ID,验证empemp_expr表对应记录是否删除
  • 批量测试:传入多个 ID(如 [1,3,5]),检查事务是否保证全部成功或回滚
  • 边界测试:传入空列表、重复 ID,验证接口是否抛出合理异常

2. 修改功能测试

  • 基本信息更新:修改姓名、手机号等字段,验证数据库是否正确更新
  • 工作经历变更:新增 / 删除工作经历条目,确保旧数据清除且新数据正确插入
  • 唯一约束测试:尝试修改手机号为已存在的值,验证是否触发唯一性异常

3. 统计功能验证

  • 数据分组:检查不同职位 / 性别的统计结果是否与实际数据一致
  • 特殊值处理:测试genderNULL的记录是否被正确归类(可自定义默认值)
  • 格式校验:确认返回数据结构符合前端图表组件的要求(如数组顺序、字段名)

📚 扩展建议

  1. 权限控制:为删除 / 修改功能添加角色校验(如仅管理员可操作)
  2. 日志审计:记录员工操作日志(操作人、时间、数据前后对比)
  3. 性能优化:对高频查询添加缓存(如使用 Redis 存储统计结果)
  4. 分页支持:在统计接口中添加分页参数,避免大数据量下性能问题

通过本指南,可完整实现企业级员工管理系统的核心功能,覆盖 CRUD、事务控制、异常处理及数据统计等关键场景,满足中大型应用的业务需求。

如对内容有异议,请联系关邮箱2285786274@qq.com修改