错误点:

LocalDate vs LocalDateTime

类型 包含信息 适配场景 前端传参格式 转换复杂度
LocalDate 年 / 月 / 日 仅日期维度的查询(如入职日期) 2010-01-01 极低(无冗余)
LocalDateTime 年 / 月 / 日 / 时 / 分 / 秒 需精确到时间的场景(如订单创建时间) 2010-01-01 12:00:00 高(需补时分秒)

致命错误:@DateTimeFormatpattern 格式(核心)

  • ❌ 错误写法:

    pattern = “yyyy-mm-dd” mm是分钟(minute),MM才是月份(month)!此错误会导致:前端传2010-01-01→ 被解析为2010-00-01(分钟 00,月份错误),触发时间转换异常。

  • ✅ 正确写法:

    pattern = “yyyy-MM-dd”

    匹配前端的2010-01-01 纯日期格式,正确解析月份。

请求参数过多

定义一个实体类,来封装这几个请求参数

动态SQL

SQL语句不应该是写死的,而应该根据用户输入的条件的变化而变化。 那这里呢,就要通过Mybatis中的动态SQL来实现。所谓动态SQL,指的就是随着用户的输入或外部的条件的变化而变化的SQL语句。

<if>:判断条件是否成立,如果条件为true,则拼接SQL。

<where>:根据查询条件,来生成where关键字,并会自动去除条件前面多余的and或or。

动态保存工作经历

这里用到Mybatis中的动态SQL里提供的 <foreach> 标签,改标签的作用,是用来遍历循环,常见的属性说明:

  1. collection:集合名称
  2. item:集合遍历出来的元素/项
  3. separator:每一次遍历使用的分隔符
  4. open:遍历开始前拼接的片段
  5. close:遍历结束后拼接的片段

上述的属性,是可选的,并不是所有的都是必须的。 可以自己根据实际需求,来指定对应的属性。

1
2
3
4
insert into emp_expr (emp_id, begin, end, company, job) values
<foreach collection="exprList" item="expr" separator=",">
(#{expr.empId}, #{expr.begin}, #{expr.end}, #{expr.company}, #{expr.job})
</foreach>

集合判空条件使用问题

1
2
3
4
List<EmpExpr> exprList = emp.getExprList();
if (exprList != null) {

}

而是用

1
2
3
4
List<EmpExpr> exprList = emp.getExprList();
if(!CollectionUtils.isEmpty(exprList)){

}

你提出的两种写法核心差异在于 「判空的严谨性」「业务数据的完整性」 —— 后者是生产环境的标准写法,前者存在空集合插入风险、且缺失核心业务逻辑(设置关联主键),具体分析如下:

一、核心差异 1:判空逻辑的严谨性(!= null vs CollectionUtils.isEmpty

问题:仅用 exprList != null 判空的致命缺陷

exprList != null 只能判断「集合引用不为空」,但无法判断「集合是空的(size=0)」。比如:

java

运行

1
2
3
4
5
// 前端传了空列表,或代码中初始化了空集合
List<EmpExpr> exprList = new ArrayList<>();
if (exprList != null) { // 条件为true,会执行insertBatch
empExprMapper.insertBatch(exprList);
}

此时会触发「批量插入空列表」的问题:

  • MyBatis 执行 insertBatch 时,会拼接空的 VALUES () 语句,直接报 SQL 语法错误;
  • 即使框架兼容空列表,也会发起无意义的数据库请求,浪费资源。

解决方案:CollectionUtils.isEmpty(exprList)(生产级判空)

CollectionUtils.isEmpty() 是 Spring/Commons Collections 提供的工具方法,同时判断「集合引用为 null」和「集合为空(size=0)」,等价于:

java

运行

1
exprList == null || exprList.isEmpty()

作用:只要集合是 null 或空列表,都跳过插入逻辑,避免无效 SQL 和报错。

二、核心差异 2:补充业务关键字段(empExpr.setEmpId(empId)

这是最核心的业务逻辑,也是前者写法完全缺失的部分:

为什么必须设置 empId

EmpExpr(员工经历)是「从表」,empId 是关联「主表 Emp」的外键,这个字段的来源通常是:

  1. 先插入主表 Emp,生成自增的 empId(比如数据库主键自增、雪花算法生成);

  2. 员工经历 EmpExpr 是前端随 Emp 一起提交的,但前端无法知道 empId(还未生成);

  3. 因此必须在插入

1
EmpExpr
前,手动给每个经历对象设置关联的
1
empId
,否则: - 数据库 `emp_expr` 表的 `emp_id` 字段为空,导致「经历数据与员工脱钩」(查不到某员工的经历); - 若 `emp_id` 字段设置了「非空约束」,直接报数据库插入失败; - 业务上形成「孤儿数据」(无归属的经历记录)。

举个完整业务流程例子:

java

运行

1
2
3
4
5
6
7
8
9
10
11
// 1. 插入主表 Emp,生成 empId(比如自增主键)
Long empId = empMapper.insert(emp);

// 2. 获取员工经历列表(前端传的,无 empId)
List<EmpExpr> exprList = emp.getExprList();

// 3. 给每个经历设置关联的 empId(核心!)
if (!CollectionUtils.isEmpty(exprList)) {
exprList.forEach(empExpr -> empExpr.setEmpId(empId));
empExprMapper.insertBatch(exprList); // 此时每条经历都有归属的 empId
}

三、两种写法的对比表

写法特点 仅判 null + 直接插入 判空集合 + 设 empId + 插入
判空逻辑 仅判断引用非 null,空列表会执行插入 同时判断 null / 空列表,跳过无效插入
业务完整性 缺失 empId,经历数据无归属 补充 empId,保证主从表关联
数据库风险 空列表插入触发 SQL 语法错误 / 非空约束报错 无无效 SQL,符合数据库外键约束
生产环境兼容性 极低(易报错、产生脏数据) 极高(标准写法)