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

浙公网安备 33010602011771号