- 发布日期
Web实战:部门查询与前后端联调
- 作者
- 姓名
- 缘
- 社交账号
文章目录
部门列表查询
部门管理的第一个功能是查询全部部门。
接口:
请求方式:GET
请求路径:/depts
请求参数:无
查询结果通过统一的 Result 返回。
三层架构中的调用流程
查询部门时,每一层的职责:
浏览器
↓ GET /depts
Controller
↓
Service
↓
Mapper
↓
MySQL
具体职责:
Controller
接收请求
调用Service
封装响应
Service
处理业务逻辑
调用Mapper
Mapper
执行SQL
访问数据库
SQL:
select *
from dept
order by update_time desc;
Mapper层
@Mapper
public interface DeptMapper {
@Select("""
select *
from dept
order by update_time desc
""")
List<Dept> findAll();
}
Service层
接口:
public interface DeptService {
List<Dept> findAll();
}
实现类:
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public List<Dept> findAll() {
return deptMapper.findAll();
}
}
Controller层
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@GetMapping("/depts")
public Result findAll() {
List<Dept> deptList = deptService.findAll();
return Result.success(deptList);
}
}
完整调用链:
GET /depts
↓
DeptController.findAll()
↓
DeptService.findAll()
↓
DeptMapper.findAll()
↓
select * from dept ...
↓
List<Dept>
↓
Result.success(...)
↓
JSON响应
MyBatis数据封装
MyBatis 查询数据后,会尝试将数据库字段自动封装到实体对象。
如果名称一致:
数据库字段:name
Java属性:name
可以直接完成映射。
但部门表中:
create_time
update_time
Java 实体类通常写成:
private LocalDateTime createTime;
private LocalDateTime updateTime;
名称不完全一致,因此需要处理映射关系。
解决字段映射问题
手动结果映射
@Results({
@Result(column = "create_time", property = "createTime"),
@Result(column = "update_time", property = "updateTime")
})
@Select("""
select id, name, create_time, update_time
from dept
order by update_time desc
""")
List<Dept> findAll();
SQL起别名
@Select("""
select id,
name,
create_time createTime,
update_time updateTime
from dept
order by update_time desc
""")
List<Dept> findAll();
开启驼峰映射
更常用的方式是在配置文件中开启:
mybatis:
configuration:
map-underscore-to-camel-case: true
之后:
create_time → createTime
update_time → updateTime
即可自动映射。
前后端联调
后端接口测试通过之后,还需要与前端项目进行联调。
前端项目运行在:
http://localhost:90
后端 Tomcat 运行在:
http://localhost:8080
前端实际发送请求:
http://localhost:90/api/depts
但后端真正的接口地址是:
http://localhost:8080/depts
这里通过 Nginx 完成反向代理。
什么是反向代理
反向代理可以理解为:客户端只访问代理服务器,再由代理服务器把请求转发到真正的后端服务器。
浏览器
↓
Nginx :90
↓
Spring Boot / Tomcat :8080
反向代理可以带来:
- 后端地址对客户端透明
- 统一请求入口
- 配置更灵活
- 可以实现负载均衡
Nginx反向代理配置
server {
listen 90;
location ^~ /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://localhost:8080;
}
}
前端发送:
http://localhost:90/api/depts
匹配:
location ^~ /api/
再通过:
rewrite ^/api/(.*)$ /$1 break;
将:
/api/depts
重写为:
/depts
最后:
proxy_pass http://localhost:8080;
转发到:
http://localhost:8080/depts
整个过程:
localhost:90/api/depts
↓
Nginx
↓ 去掉 /api
localhost:8080/depts
↓
Spring Boot
小结
查询部门这个功能把后端 Web 的完整调用链串了起来:
前端
↓
Nginx
↓
Controller
↓
Service
↓
Mapper
↓
MySQL
同时还涉及 MyBatis 自动结果封装、下划线转驼峰以及 Nginx 反向代理。