1. 多表关系
-
三种关系:一对多 / 一对一 / 多对多
-
一对多(部门-员工) :在“多”的一方
emp增加dept_id关联dept.id -
删除部门导致“员工仍指向该部门”→ 数据不一致
- 物理外键(foreign key):能保证一致性,但影响性能/不适合集群,企业常禁用
- ✅ 逻辑外键:不建外键,靠业务逻辑保证一致性(更常用)
-
一对一:任意一方加外键 +
UNIQUE- 主要用于单表拆分 (如用户基本信息 vs 身份证信息)
-
多对多:建中间表(含两个外键字段)
-
如学生 vs 课程。
-
实现方式:引入第三张中间表,中间表包含两个外键。
-
2. 多表查询
-
多表直接
from emp, dept会产生笛卡尔积 → 必须加关联条件 -
连接查询
- 内连接:查交集
- ✅ 外连接:左外/右外(员工列表常用左外连接,保证没部门的员工也能查出来)
-
子查询:标量/列/行/表子查询(本质:先拆步骤,再合成一条SQL)
3. 员工列表查询(重点实战)
3.1 基础准备
-
表:
emp、dept(可扩展emp_expr工作经历表) -
实体类:
Emp多一个deptName用于封装部门名称 -
多表查询SQL(左外连接):
select e.*, d.name as deptName from emp e left join dept d on e.dept_id = d.id
3.2 分页查询
-
SQL分页:
limit start, pageSize,start = (page-1)*pageSize -
返回结构:
PageResult(total, rows) -
两种实现:
-
原始分页:Mapper 写
count()+list(limit...),Service 计算 start -
✅ PageHelper(推荐):
PageHelper.startPage(page,pageSize)- Mapper 正常查询(不写 limit)
- 结果转
Page<Emp>取total + result
-
-
注意:SQL末尾不要加
;,PageHelper只拦截后面第一条查询 -
可配置合理化:
pagehelper.reasonable=true(页码<=0查第一页,超范围查最后一页)
3.3 条件分页查询
-
条件:姓名模糊、性别精确、入职日期范围
-
Controller 接收参数(日期用
@DateTimeFormat) -
✅ 参数多时用
EmpQueryParam封装(含默认 page=1/pageSize=10) -
Mapper SQL 建议放 XML,并用 动态SQL:
<if>:按条件拼接<where>:自动生成 where 并去掉多余 and/or
——