Java笔记-24、Web后端实战-员工管理-删除修改员工

删除员工

其实,删除单条数据也是一种特殊的批量删除,所以,删除员工的功能,我们只需要开发一个接口就可以了。

Controller接收请求参数

  • 方式一:在Controller方法中通过数组来接收,ids和传来的参数名相同
@DeleteMapping
public Result delete(Integer[] ids) {
    log.info("删除员工:{}", Arrays.toString(ids));
    empService.delete(ids);
    return Result.success();
}
  • 方式二:在Controller方法中通过集合来接收(推荐)方便使用List的各种操作
@DeleteMapping
public Result delete(@RequestParam List<Integer> ids) {
    log.info("删除员工:{}", ids);
    empService.delete(ids);
    return Result.success();
}

<delete id="deleteByIds">
  delete from emp where id in
  <foreach collection="ids" item="id" separator="," open="(" close=")">
    #{id}
  </foreach>
</delete>

修改员工

查询回显+修改数据

多结果处理-手动封装

select e.*,
        ee.id ee_id,
        ee.emp_id ee_empid,
        ee.begin ee_begin,
        ee.end ee_end,
        ee.company ee_company,
        ee.job ee_job
        from emp e left join  emp_expr ee on e.id = ee.emp_id
        where e.id = #{id}

按照上述SQL语句,如果一个员工有多条工作经历,返回的是多条数据,但是按照接口规定,需要返回给前端一条封装好的员工基本信息和工作经历信息。

如此,不能使用MyBatis的自动结果封装,需要手动封装。

不能使用resultType而是使用resultMap自定义结果集。

<resultMap id="empResultMap" type="com.study.pojo.Emp">
   <id column="id" property="id"/>
   <result column="username" property="username"/>
   <result column="password" property="password"/>
   <result column="name" property="name"/>
   <result column="gender" property="gender"/>
   <result column="phone" property="phone"/>
   <result column="job" property="job"/>
   <result column="salary" property="salary"/>
   <result column="image" property="image"/>
   <result column="entry_date" property="entryDate"/>
   <result column="dept_id" property="deptId"/>
   <result column="create_time" property="createTime"/>
   <result column="update_time" property="updateTime"/>
   <collection property="exprList" ofType="com.study.pojo.EmpExpr">
       <id column="ee_id" property="id"/>
       <result column="ee_empid" property="empId"/>
       <result column="ee_begin" property="begin"/>
       <result column="ee_end" property="end"/>
       <result column="ee_company" property="company"/>
       <result column="ee_job" property="job"/>
   </collection>
</resultMap>
<select id="getById" resultMap="empResultMap">
   select e.*,
   ee.id ee_id,
   ee.emp_id ee_empid,
   ee.begin ee_begin,
   ee.end ee_end,
   ee.company ee_company,
   ee.job ee_job
   from emp e left join  emp_expr ee on e.id = ee.emp_id
   where e.id = #{id}
</select>

按照实体类一个属性一个属性地封装,主键用id标签封装,普通属性用result标签封装,List集合用Collection标签封装。

如果查询返回的字段名与实体的属性名可以直接对应上,用resultType。

如果查询返回的字段名与实体的属性名对应不上,或实体属性比较复杂,可以通过resultMap手

动封装。

修改不确定数量数据-先删后加

修改基本信息好说,修改工作经历可能增加、删除、修改信息,应该遵循一个原则:先删后加。

更新优化-动态SQL

上述更新基本信息,要前端传递所有的字段值才能正确更新,如何只想修改用户名,传递的参数只有用户名就不能用上述的修改方法了。

如何动态更新,增强扩展性和灵活性呢?

使用动态SQL,用<if>来判断更新。

<set>:自动生成set关键字;会自动删除更新字段后多余的逗号。

<update id="updateById">
   update emp
   <set>
       <if test="username != null and username != ''">username = #{username},</if>
       <if test="password ">password = #{password},</if>
       <if test="name != null and name != ''">name = #{name},</if>
       <if test="gender != null">gender = #{gender},</if>
       <if test="phone != null and phone != ''">phone = #{phone},</if>
       <if test="job != null">job = #{job},</if>
       <if test="salary != null">salary = #{salary},</if>
       <if test="image != null and image != ''">image = #{image},</if>
       <if test="entryDate != null">entry_date = #{entryDate},</if>
       <if test="deptId != null">dept_id = #{deptId},</if>
       <if test="updateTime != null">update_time = #{updateTime}</if>
   </set>
   where id = #{id}
</update>

异常处理-全局异常处理器

现在异常处理都是交给了框架,返回的是框架的默认模板,具体出现的问题不清楚。

一种方法是用try-catch,catch里是return Result.error("问题");这种方式代码相当臃肿!

另一种方式是spring框架提供的全局异常处理器,全局异常处理器捕获到异常,会返回给前端一个异常结果。

核心注解:@RestControllerAdvice以及@ExceptionHandler

新建包exception并新建类GlobalExceptionHandler。

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler
    public Result handleException(Exception e){ // 捕获所有异常
        log.error("程序出错-",e);
        return Result.error("出错,请联系管理员"); // 前端看到的信息
    }
    @ExceptionHandler
    public Result handleDuplicateKeyException(DuplicateKeyException e){
        log.error("唯一值重复-",e);
        String message = e.getMessage();
        int i = message.indexOf("Duplicate entry");
        String errMsg = message.substring(i);
        String[] arr = errMsg.split(" ");
        return Result.error(arr[2] + "已被使用,请更换");
    }
}

如果发生DuplicateKeyException,框架会根据错误的继承关系从下往上进行匹配。会先匹配到DuplicateKeyException,如果没有处理这个异常的方法,会往上匹配直到Exception。

员工信息统计

报表用百度的Echarts

员工职位统计响应代码块

{
  "code": 1,
  "msg": "success",
  "data": {
    "jobList": ["教研主管","学工主管","其他","班主任","咨询师","讲师"],
    "dataList": [1,1,2,6,8,13]
  }
}

应该新建实体类,封装jobList和dataList。

select job,count(*) from emp group by job;

现在job都是数字指代,如何将数字映射到名称上,要用到SQL的case函数。

select 
(case job 
when 1 then '班主任' 
when 2 then '讲师' 
when 3 then '学工主管' 
when 4 then '教研主管' 
when 5 then '咨询师' 
else '其他' end) position,
count(*) number
from emp group by job
order by number;

-- 或者
-- 第二种更通用,可以范围匹配

select 
(case 
when job=1 then '班主任' 
when job=2 then '讲师' 
when job=3 then '学工主管' 
when job=4 then '教研主管' 
when job=5 then '咨询师' 
else '其他' end) position,
count(*) number
from emp group by job
order by number;

注意when-then和end。

Slf4j
@RequestMapping("/report")
@RestController
public class ReportController {
    @Autowired
    private ReportService reportService;
    @GetMapping("/empJobData")
    public Result getEmpJobData(){
        log.info("统计员工职位人数");
        JobOption empJob = reportService.getEmpJonData();
        return Result.success(empJob);
    }
}
@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private EmpMapper empMapper;
    @Override
    public JobOption getEmpJonData() {
        // map集合: position=,number=
        List<Map<String, Object>> list = empMapper.countJobData();
        List jobList = list.stream().map(dataMap -> dataMap.get("position")).toList();
        List dataList = list.stream().map(dataMap -> dataMap.get("number")).toList();
<Object>
<Object>
        return new JobOption(jobList, dataList);
    }
}
List<Map<String, Object>> countJobData();

员工性别统计响应

{
  "code": 1,
  "msg": "success",
  "data": [
    {"name": "男性员工","value": 5},
    {"name": "女性员工","value": 6}
  ]
}
@GetMapping("/empGenderData")
public Result getEmpGenderData(){
    log.info("统计员工性别人数");
    List<Map<String, Object>> empGender = reportService.getEmpGenderData();
    return Result.success(empGender);
}
@Override
public List<Map<String, Object>> getEmpGenderData() {
    return empMapper.countEmpGenderData();
}
List<Map<String, Object>> countEmpGenderData();
<select id="countEmpGenderData" resultType="java.util.Map">
   select
   if(gender = 1 , '男性员工', '女性员工') name,
   count(*) value
   from emp group by gender
</select>

if(expr,val1, val2):如果表达式expr成立,取val1,否则取val2

ifnull(expr,val1):如果expr不为null,取自身,否则取val1

posted @ 2025-04-08 23:46  subeipo  阅读(32)  评论(0)    收藏  举报